在C#中调用和调试C++代码

在使用.NET开发时,由于种种原因,可能希望使用C++编写部分代码,例如希望通过使用C++提高性能,或是希望重用既有的代码。而.NET平台提供了平台调用(P/Invoke)功能,可以方便地调用其他语言编写的动态链接库(dll)。平台调用功能可以在各种.NET环境,包括.NET Core、.NET Framework、UWP下使用。

C++部分

本节以Visual C++ 2017为例,介绍如何用C++编写一个动态链接库。

打开Visual Studio 2017,点击“新建项目”,选择Visual C++ -> Windows桌面 -> 动态链接库(DLL),新建一个动态链接库项目,命名为TestLibrary。

在TestLibrary.cpp文件末尾的空白处插入以下代码:

extern "C" __declspec(dllexport) double __stdcall Add(double a, double b)
{
    return a + b;
}

一个最简单的动态链接库就编写完成了。__declspec(dllexport)表示这个函数需要导出到dll中供其他程序调用。__stdcall表示调用方式是stdcall(即由被调用方清理栈)。extern "C"表示以C的格式进行导出(方便用C++以外的语言进行调用)。

在Visual Studio工具栏中将解决方案平台设置为与操作系统对应的平台(32位操作系统选择x86,64位操作系统选择x64),点击菜单中的生成 -> 生成解决方案进行生成。生成好的文件在解决方案文件夹内的Debug文件夹(x86)或x64/Debug文件夹(x64)内,在下面的步骤中中会用到TestLibrary.dll和TestLibrary.pdb这两个文件。

调用

本节介绍如何用C#在.NET程序中调用动态链接库。

打开Visual Studio 2017,点击“新建项目”,选择Visual C# -> .NET Core -> 控制台应用(.NET Core),或是Visual C# -> Windows桌面 -> 控制台应用(.NET Framework),新建一个控制台应用项目。

右键单击“解决方案资源管理器”内的项目名称,点击添加 -> 现有项,将右下角文件类型改为“所有文件”,选择刚才生成的TestLibrary.dll和TestLibrary.pdb文件,将它们添加到项目中。在解决方案资源管理器中选择这两个文件,右键单击,选择属性,在属性窗口中将生成操作改为“内容”,复制到输出目录改为“始终复制”。

在Program.cs文件内的Program类中插入以下代码,以声明dll中的函数:

//using System.Runtime.InteropServices;
[DllImport("TestLibrary.dll", CallingConvention = CallingConvention.StdCall)]
extern static double Add(double a, double b);

然后就可以在主程序中调用这个函数了:

Console.WriteLine(Add(1, 2));

调试

上文中提到的TestLibrary.pdb文件是调试数据库文件,是Visual Studio的断点、监视功能所必需的。在默认设置下,Visual Studio调试器会自动发现跟dll文件处在相同文件夹内的pdb文件。但要在.NET项目中开启C++代码调试,还需要一些步骤。

.NET Framework

在.NET Framework的项目属性中选择“调试”项目,勾选“启用本地代码调试”,即可调试C++代码。

.NET Core

.NET Core的调试设置中暂时没有“本地代码调试”的功能,但可以通过别的方法开启本地代码的调试。在Visual Studio的“调试”菜单中选择“开始执行(不调试)”,直接启动.NET Core应用,然后在“调试”菜单中选择“附加到进程”,点击“附加到:”后的“选择”按钮,勾选调试代码类型“CoreCLR”和“本机”,然后附加到“dotnet.exe”后即可调试C#和C++代码。

留言

向我们提问或者评论我们的文章。您的留言不会被直接显示在网站内。
请在浏览器中启用JavaScript来完成此表单。
Email