使用C#调用C++类库
环境:win10+VS2017
过程介绍:
1.使用C++编写一个动态库(DLL);
2.将DLL内函数导出;
3.使用C#进行调用;
4.方法调用说明;
5.C#代码到C++代码的调试问题;
1.使用C++编写简单的DLL;
1.1创建项目(x64);
在VS2017中新建->项目->Visual C++->Windows桌面->动态链接库;
在项目属性中->常规中选择无公共语言支持,即不创建托管C++类库;
1.2添加类和方法;
在该类的.cpp文件中声明方法;
自定义一个结构体
在方法的参数中使用结构体,
方法种类:
A类: int TestFunc(int a);
B类:int Funci2(char * c);
C类:char * Funcc(int a);
D类:char Funcc2();
E类: int GetMyIntroStruct(MyIntroStruct* mystr, int* c);
F类:int SetMyIntroStruct(MyIntroStruct mystr, int index);
1.3 将方法导出;
这里使用extern "C" __declspec(dllexport)标记方法的方式进行导出;
也可以使用.def文件进行导出;
;.def文件的规则 ; (1)LIBRARY语句说明.def文件相应的DLL ; (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用) ; (3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行 ;HelloWorld.dll : 导出DLL函 LIBRARY HelloWorld.dll EXPORTS AddE @ 1 SubE @ 2
2 编译完后,使用Denpends工具,打开该dll,查看C++代码中被标记导出的函数是否都已导出;
3.在C#中进行添加和调用;
这里采用DllImport特性标记方式进行导入
这里需要注意C++参数类型和C#参数类型的对应问题,以及内存空间哪一方申请和写入的问题。
在C#类中添加相应结构的自定义结构体(注意结构体的顺序),指定结构的内存分布为顺序分布;
4.方法调用;
对于参数传入类型:
A类,B类方法,可以直接调用;
对于Inptr参数的方法,可以在C#内申请内存空间传入C++中进行赋值,并需要对指针释放;(这里有自定义的c++函数预先提供相关函数的输出数组大小)
对于传出的参数Intptr类型的可以进行数据读取,将Intptr转换为string类型:
对于自定义结构体的Intptr指针可以通过对指针偏移获取数据:
5.调试问题;
在同一个vs工程中,使用单步调试可以从C#调用代码逐步调试到C++被调用代码中
开源演示代码:cs2cpp - https://gitee.com/lzz42/cs2cpp