首先,问什么会出现C#程序调用C++编写的DLL文件呢?下面简单描述一下这种情况的背景。在新开发的项目中使用的新语言C#和新的技术方案webService,
但是在新项目中,一些旧的模块仍需要使用,一般采用C、C++或Delphi编写,如何利用旧模块对与开发人员有三种方法可选择:
- 彻底改写,你懂得,C++中的指针和内存的操作,改写成C#是一件非常头疼事。
- 将C或C++函数封装成COM,在C#中调用COM,还是比较方便。只需要做一些数据类型的转化,但是COM需要注册啊,多次注册多造成混乱的,也着实头疼。
- 将C或C++函数封装成DLL, 封装过程简单,工作量也比较小。C#调用C++或C的DLL,注意两个问题:a,数据类型转化。b,对指针和内存的转化。这两点还是比较容易解决的。
技术实现
- 创建一个TestDLL的项目,项目类型是ClassLibrary。
- TestDll.cpp文件中添加如下代码。
#include <iostream> using namespace std; int MyAdd(int a,int b) { return a+b; } char* MyChar(char* a,char** b) { sprintf((*b),"%s",a); char *c = (char*)malloc(sizeof(char*)*strlen(a)); strcpy(c,a); return c; }
- TestDLL.h文件添加如下代码。
#ifdef Import #define Import extern "C" _declspec(dllimport) #else #define Import extern "C" _declspec(dllexport) #endif Import int MyAdd(int a,int b); Import char * MyChar(char* a,char* b);
- 添加一个文件def的文件,命名为TestDLL.def。添加如下代码。
LIBRARY "TestDLL" EXPORTS MyAdd @1 MyChar @2
- 进行编译,生成相应的DLL和Lib文件。
- 在该解决方案下,添加一个C#的新项目,调用TestDLL.DLL,项目名称为 CSharpCallCPPDll,(名字起的有点长),创建一个consoleApplication的项目。完事后,添加TestDLL.DLL的引用。(如果这个还不会,回家补补课再看吧)。
- 在Class Program中导入TestDLL中的函数,导入代码如下。
[DllImport("TestDLL.dll", EntryPoint = "MyAdd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] public static extern int MyAdd(int a, int b); [DllImport("TestDLL.dll", EntryPoint = "MyChar", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall )] public static extern string MyChar(string a, ref string b);//注意与C++函数的数据类型的转化
- 测试代码:
int c = MyAdd(1, 3); Console.WriteLine("1+3=" + c); try { string strA = "1234abcs汉字也支持吧"; string strB = ""; string str = MyChar(strA,ref strB); Console.WriteLine("---C#--CALL----"); Console.WriteLine("A="+strA); Console.WriteLine("B=" + strB); Console.WriteLine("return Str=" + str); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read();
- 以上完成了C#程序调用C++的DLL文件。