閑暇之余,記一下筆記!記錄一下c#如何調用C++的動態庫(dll).
步驟:
一、創建一個C++類,例如:
AddOperate.h
1 extern _declspec(dllexport) int Sum(int a, int b); 2 class AddOperate 3 { 4 public : 5 };
AddOperate.cpp
1 #include "AddOperate.h"
2 #include "iostream"
3 using namespace std; 4
5 int Sum(int a, int b) 6 { 7 if (a - (int)a != 0 || b - (int)b != 0) { 8 cout << "請輸入整數" << endl; 9 return -1; 10 } 11 return a + b; 12 }
2、將C++代碼編譯成動態庫dll
需要設置編譯配置:
A:項目--屬性---賠指數型--常規---配置類型---動態庫(.dll)
B:項目--屬性--配置屬性--C/C++---高級---編譯為---便以為C++代碼(/TP)
這個活動X64注意,調用放C#最好也用這個X64;
然后點擊項目--生成,就會看到dll了;
3、將dll拷貝到c#項目輸入目錄,一般在bin/debug下面;
4、編寫C#代碼調用dll
1 [DllImport("Calculate.dll", CallingConvention = CallingConvention.Cdecl)] 2 extern static int Sum(int a, int b); 3 public static void Main(string[] args) { 4 try { 5 Console.WriteLine("請輸入NumberA:"); 6 int numberA = Convert.ToInt32(Console.ReadLine()); 7
8 Console.WriteLine("請輸入NumberB:"); 9 int numberB = Convert.ToInt32(Console.ReadLine()); 10
11 Console.WriteLine($"the numberA is:{numberA};numberB is:{numberB},The Sum is:{Sum(numberA, numberB)}"); 12
13 } 14 catch(Exception ex) { 15 Console.WriteLine($"ex:{ex}"); 16 } 17
18 Console.ReadLine(); 19 }
主要是這兩行:
這個“Sum”方法必須跟dll方法名字相同,否則找不到;
接下來看看運行結果:
很尷尬,提示找不到“Sum”方法,難道我們的操作有問題。
排查了很久,發現C++方法編譯成dll時,方法名會改變,也是為了安全;
解決方案:
要把C++代碼轉化成C語言!
就這樣,然后再編譯dll過來,再次執行:
結果:成功
五、其他可能遇到的問題
A:對PInvoke函數的調用導致堆棧不對稱問題
方法定義加:CallingConvention = CallingConvention.Cdecl
B:未處理System.BadImageFormatException,試圖加載格式不正確的程序。 (異常來自 HRESULT:0x8007000B)
就這樣OK了!。
六:思考:如果這個dll中有多個方法需要調用,
該怎么辦,是否是這樣,一個個聲明引用??