综述
C# 调用 C++ 中的函数或类是通过调用其 dll 来实现的。对于 unmanaged C++,我们在每个函数前加上 dllexport
,并在 C# 代码中通过 dllimport
和 extern static
来调用 dll 中的函数。这样需要为每个函数添加 dllimport/dllexport
,很不方便。注意 C# 是可以直接调用 C++/CLR (managed C++) 的 dll 的。因此,为了两端(调用端/实现端)代码编写的便利,我们可以用 C++/CLR 作为联系 unmanaged C++ 和 C# 的 wrapper,写出更简洁的代码。
C# 调用 C++ 代码 —— dllimport 方式
编写 C++ DLL
新建 VC++ 控制台空项目,项目类型选 DLL,新建 MathFuncDll.h 和 MathFuncDll.cpp 文件,代码如下:
|
|
|
|
编译后在 Debug 或 Release 文件夹中可找到 MathFuncsDll.dll 文件。
编写 C# 测试程序
新建 C# 控制台项目,Program.cs 的代码如下:
|
|
运行后输出 20
代表程序正确。
C# 调用 C++ 代码 —— C++ wrapper 方式
以上代码能够正确运行。但是需要 dllimport/dllexport
,且调用时每个函数需要定义 static extern
。当函数数量不多时,这种方法容易使用。但当函数数量很大时,调用会很不方便。
注意到虽然 C# 调用普通的 C++ 代码(unmanaged C++)很麻烦,但 C# 是可以直接调用 C++/CLI (managed C++) 的 dll 的。C++/CLI 即托管的 C++ —— 以 C++ 的名义写 C#。CLI 是 Common Language Infrastructure 的缩写。所以我们可以将 C++/CLI 作为 C++ 和 C# 的接口 —— 为 C++ 程序写一个 wrapper,然后在 C# 里直接调用。
简而言之,需要三个项目:
- 一个 VC++ 项目,采用 unmanaged C++,编写主要的函数体;
- 一个 VC++ 项目,采用 managed C++,编写 C++/CLI wrapper;
- 一个 VC# 项目,测试 C++/CLI wrapper 的 dll。
C++ 主体代码
建立 VC++ 空项目,项目类型为控制台应用程序,建立 MathFuncs.h, MathFuncs.cpp 和 main.cpp 文件,其中 main.cpp 主要用于测试 MathFuncs.cpp 中的函数。代码如下:
|
|
|
|
|
|
代码无误的话运行会出现 “Result is 30.300000”。
C++ wrapper 代码
新建 VC++ CLI Class Library 项目 managedDllWrapper,修改 managedDllWrapper.h 和 managedDllWrapper.cpp 如下:
|
|
|
|
以 Debug 或/和 Release 模式编译后会生成 managedDllWrapper.dll 文件。我们将在 C# 中使用它们。
C# 测试代码
新建 C# 控制台应用程序,在 References
中右键添加,选择 Browse...
找到 managedDllWrapper.dll 并添加,即可直接在 C# 代码中使用 dll 中的函数。C# 测试代码如下:
|
|
运行无误应该出现结果 20
和 40
。
C# 调用 C++ OpenCV 代码
在 rich UI 的 C# 中调用 rich efficiency 的 C++ OpenCV 代码,结合二者的优势。