如何从C#访问C ++ / CLI中的类?

我正在用C#编写GUI工具来解析和显示用C编写的另一个程序的数据输出。为了解析数据,我需要知道在多个C头文件中指定的数据结构。 因此,我需要将这些C头文件合并到我的C#项目中。 我的问题是:

1)经过一些研究后我得出结论,最好的方法是在我的解决方案中创建一个新的C ++ / CLI项目,将C头文件导入到这个新项目中,编写一些C ++ / CLI类作为数据的薄包装器在C头文件中定义的结构,然后从C#代码引用C ++ / CLI包装器类。 这是最好的方法,还是有更好的方法?

2)我遇到了参考问题。 这是我的简化代码来说明问题:

C ++ / CLI项目中的原始C头

#define ABC 0x12345 

C ++ / CLI项目中的包装类

 #include "my_c_header.h" namespace C_Wrappers { public ref class MyWrapper { public: property unsigned int C_ABC { unsigned int get() { return ABC; } } } } 

C#项目中的用户类

 using C_Wrappers; using System; namespace DataViewer { public partial class MainForm : Form { private MyWrapper myWrapper = new MyWrapper(); public MainForm() { Console.WriteLine(myWrapper.C_ABC.ToString()); } } } 

在C#项目中,我添加了对C ++ / CLI项目的引用(使用右键单击>添加引用)。 在构建期间,我在C#项目中遇到错误:“找不到类型或命名空间’C_Wrappers’(你是否缺少using指令或程序集引用?)。”

我以为我做了我应该做的一切。 我该怎么做才能解决这个错误?

当我需要使用WPF将C ++链接到C#时,我发现这个链接非常有用。 不幸的是,它是用法语写的,所以我链接了谷歌提供的翻译版本。

在我自己的解决方案中,我有4个项目:

  1. C ++项目和测试代码
  2. C ++ DLL项目 ,它只使用动态链接从第一个项目源编译DLL
  3. 包装器项目 ,它只是一个使用C ++ / CLI的适配器,它包装了原始C ++
  4. C#WPF项目是我的图形界面。

这是我上面提供的链接的翻译。

C ++ DLL项目

将您的C ++代码转换为DLL库。

  1. 在Visual Studio中,转到文件>新建>项目 ,从Visual C ++选项卡中选择Win32项目
  2. 为项目和解决方案选择一个名称,解决方案将包含所有项目。
  3. 在Win32应用程序的助手中,单击下一步 ,选中DLL框,然后单击清空项目,然后单击完成

项目创建项目助手

要添加的代码

这是我的dll的C ++标题(减去很多东西)。

Token.h

 #pragma once #define DLLEXP __declspec( dllexport ) DLLEXP void pop_back(std::string& str); DLLEXP std::string testReturnString(); DLLEXP int getRandomNumber(); 

CPP内部没有任何改变。

构建项目,你应该有一个DLL和一个LIB文件包含在C#项目调试目录中。

C ++ / CLI包装器

该项目用作前一个项目的本机代码和GUI的托管代码之间的接口。

  1. 在解决方案中添加一个新项目(Visual C ++中的类库)(在此示例中称为“Wrapper”)
  2. 使用其他Include目录添加本机项目的路径
  3. 添加本机项目作为新项目的参考( 右键单击>引用…>添加新链接
  4. 在“ 属性”>“链接器”>“输入”中 ,将本机dll的名称放在DLL的延迟加载中(本例中为Computations.dll)字段

C ++ / CLI代码

我的包装器只是一个看起来像这样的类(减去我自己的代码)。

Wrapper.h

 #include "Token.h" // include your C++ header #include  #include  namespace Wrapper { // noticed the ref? public ref class TokenAnalyzer { public: TokenAnalyzer(){ }; void Init(); // use the C++/CLI type, like String^ (handles) System::String^ ProcessLine(int lineNbr, System::String^ line); }; } 

除了必须包含#include "stdafx.h"之外,CPP中没有任何特殊内容。

它还应该构建一个DLL,你将包含在C#debug目录中。

只是一个有用的function,我发现在某处,但不记得你可能需要的地方。 它将C ++ / CLI字符串句柄转换为C ++标准字符串。

 std::string MarshalString (String ^ s) { using namespace Runtime::InteropServices; const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); std::string os = chars; Marshal::FreeHGlobal(IntPtr((void*)chars)); return os; } 

C#项目

向解决方案添加一个新项目( C#Windows窗体WPF或任何您想要的!)并将其设置为启动项目( 右键单击>设置为启动项目 )。

  1. 添加C ++ / CLI项目作为新项目的参考
  2. using Wrapper;添加指令using Wrapper; 源代码forms

使用它像:

 /// Store the C++/CLI Wrapper object. private Wrapper.TokenAnalyzer mTokenAnalyzer = new TokenAnalyzer(); 

更新2016/05/06

Ashwin花时间制作了一个示例项目和博客文章教程 ,可能会有所帮助。

对我来说, 这个类似问题的答案解决了C#中的同样错误。

(即我在C ++ \ CLI项目中有一个包装器头文件,但是忘了包含一个.cpp文件(尽管它只有两行:#include“stdafx.h”和#include“Wrapper.h “))