1. 程式人生 > >C#動態呼叫C++的Dll

C#動態呼叫C++的Dll

C#動態呼叫C++Dll函式

1.動態呼叫dll需要使用LoadLibrary, GetProcAddress, FreeLibrary 3個系統的API函式,所以C#中用一個類靜態呼叫kernal32.dl. 如下:

class  DllTest

{

// 呼叫API庫函式

[DllImport("Kernel32")]

public static extern int LoadLibrary(String funcname);

[DllImport("Kernel32")]

public static extern int GetProcAddress(int handle,String

funcname);

[DllImport("Kernel32")]

public static extern int FreeLibrary(int handle);

}

2.然後在同一個類中將通過非託管函式名轉換為對應的委託,如下

///<param name="dllModule">通過LoadLibrary獲得的DLL控制代碼</param>

///<param name="functionName">非託管函式名</param>

///<param name="t">對應的委託型別</param>

///<returns>

委託例項,可強制轉換為適當的委託型別</returns>

publicstaticDelegateGetFunctionAddress(intdllModule, stringfunctionName, Typet)

{

intaddress = GetProcAddress(dllModule, functionName);

if (address == 0)

returnnull;

else

returnMarshal.GetDelegateForFunctionPointer(newIntPtr(address), t);

}

3.在函式呼叫的Namespace中申明一個委託

TestFun

是委託名,裡面的引數是C++Dll中被呼叫函式的引數;

delegate void TestFun(int i);

4.呼叫第一步引用的靜態函式Loadlibrary,C#中沒有定義HMODULE這個型別,所以這個地方用int型別:

int module = DllTest.LoadLibrary("TESTCSharp.dll");

if(module==0)

{

MessageBox.Show("LoadLibrary failed");

}

else{

MessageBox.Show("LoadLibrary success");

}

5.定義一個委託型別的變數, 呼叫第二步通過非託管函式名轉換為對應的委託.並將其返回型別強制轉化成定義的委託型別,並賦值給新建立的委託實力,呼叫委託的例項化.

Type _t = typeof(TestFun);

TestFun _test = (TestFun)DllTest.GetFunctionAddress(module, "mySum", _t);

_test(3);

6.最後需要釋放建立的物件

DllTest.FreeLibrary(module);