首先,問什麼會出現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文件。