700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C#调用C++生成的dll

C#调用C++生成的dll

时间:2020-03-16 11:22:31

相关推荐

C#调用C++生成的dll

1 新建工程

(1)首先新建C#控制台工程,文件—新建—项目,选择控制台应用,如下图所示:

(2)在此工程中添加C++的动态链接库项目,右键解决方案(注意这里是解决方案,不是C#工程),选择添加,选择新建项目,如下图:

(3)在添加新建项目的界面,选择VC++下面的Win32,然后选Win32项目,修改对应文件名称,如下图:

(4)点击确定后进入设置向导,在应用程序类型中选择DLL,在附加选项中勾选导出符号和预编译头,点击确定即可(若熟练流程后,可自行添加文件,不勾选该选项)。

(5)开始编写代码。打开刚才添加的文件的,打开cpp和h文件如下图,这里是模板生成的文件,可根据需要删除,此处删除该模板生成的代码。

在CPPDLL.cpp文件写测试代码如下:

//cpp文件int num = 0;CPPDLL_API int getnum(void){return num;}CPPDLL_API void setnum(int n){num = n;}CPPDLL_API int intadd(int a, int b){int tmp = a + b;return tmp;}

在CPPDLL.h文件写测试代码如下:

#ifdef CPPDLL_EXPORTS#define CPPDLL_API __declspec(dllexport)#else#define CPPDLL_API __declspec(dllimport)#endifCPPDLL_API int intadd(int a, int b);CPPDLL_API int getnum(void);CPPDLL_API void setnum(int n);

点击生成解决方案,即可生成dll。使用Dependency Walker打开该dll文件,查看生成的dll中的函数

2 联合调试

在上一步中将dll完成后,现在来写Csharp的测试程序,程序如下:

在命名空间中加入下面这句话,表示调用外部dll,使用DllImport

using System.Runtime.InteropServices;

主程序如下:

class Program{[DllImport("CPPDLL.dll", EntryPoint = "intadd", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false)]public extern static int intadd(int a, int b);[DllImport("CPPDLL.dll", EntryPoint = "setnum", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false)]public extern static void setnum(int n); [DllImport("CPPDLL.dll", EntryPoint = "getnum", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false)]public extern static int getnum();static void Main(string[] args){int aa = 1, bb = 2;int cc = 5;Console.WriteLine(aa);Console.WriteLine(bb);Console.WriteLine(cc);var sum = intadd(aa, bb);Console.WriteLine(sum);cc = getnum();Console.WriteLine(cc);setnum(10);cc = getnum();Console.WriteLine(cc);Console.ReadLine();}}

联合调试前的准备:

首先选择dll项目,右键–属性–常规,设置如下(注意标记的地方):

这里设置输出目录的原因是:在DllImport(“CPPDLL.dll”)时设置的是相对路径,即exe文件与dll文件在同一个文件夹下,也可以改为绝对路径,如DllImport(“E:\desktop\Csharp_demo\Csharp_demo\bin\Debug\CPPDLL.dll”),但不建议这么做,因为当生成的exe在其他电脑上运行时,这种情况下exe一般与dll在一个文件夹,使用相对路径更好,使用绝对路径可能会报错。

然后选择C#控制台项目,右键–属性–调试,设置如下:

接着就可以开始进入调试模式,先在需要调试的地方添加断点,然后点击生成解决方案(注意每次修改dll中的函数后,最好选择重新生成解决方案,以便更新生成的dll),然后点击启动即可进行调试。

最后的调试结果如下:

3 相关问题的总结

3.1 运行编译平台问题

关于dll版本与C#控制台版本的问题。x86的dll在x86的C#控制台上肯定是可以运行的,x64同理。下面主要讨论,x86的dll在x64的C#控制台上是否可以运行以及x64的dll在x32的C#控制台上是否可以运行。

首先测试dll为x64版本,将dll设置x64版本,然后选择C#工程,右键–属性–生成,找到目标平台,选择x86。测试对比,如下表所示:

报错(其他信息:试图加载格式不正确的程序,异常来自HRESULT:0x8007000B)具体情况如下图:

结论:x64的exe可以运行x86和x64的dll,但x86的exe只能运行x86的dll。因此使用动态链接的时候应特别注意版本,在发布的时候应用realease版本的dll。

3.2 运行环境问题

当将本地生成的exe与dll在其他电脑上运行时,会出现如下错误:

找不到dll,错误代码0x8007007e

错误原因:该电脑未安装Visual C ++ Redistributable Packages(dll由VS编译,其他的找对应版本即可)

解决办法:

方法1、安装Visual C ++ 2105 Redistributable Packages组件

方法2、在编译dll之前,“项目属性–C/C+±-代码生成”,“运行库改”为“多线程(/MD)”;

“项目属性–链接器–系统”, “所需的最低版本”,修改为“5.01”。

踩过了许多坑,发现CSDN上面写的方法,好多都没效果,最后是google找到的。。。。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。