C 呼叫DLL函式方法(下)

2021-05-24 06:09:14 字數 3828 閱讀 8582

本文的內容接著c#呼叫dll函式方法(上)。

因為c#中使用dllimport是不能像動態load/unload assembly那樣,所以只能借助api函式了。在kernel32.dll中,與動態庫呼叫有關的函式包括[3]:

①loadlibrary(或mfc 的afxloadlibrary),裝載動態庫。

②getprocaddress,獲取要引入的函式,將符號名或標識號轉換為dll內部位址。

③freelibrary(或mfc的afxfreelibrary),釋放動態鏈結庫。

它們的原型分別是:

hmodule loadlibrary(lpctstr lpfilename);

farproc getprocaddress(hmodule hmodule, lpcwstr lpprocname);

bool freelibrary(hmodule hmodule);

現在,我們可以用intptr hmodule=loadlibrary(「count.dll」);來獲得dll的控制代碼,用intptr farproc=getprocaddress(hmodule,」_count@4」);來獲得函式的入口位址。

但是,知道函式的入口位址後,怎樣呼叫這個函式呢?因為在c#中是沒有函式指標的,沒有像c++那樣的函式指標呼叫方式來呼叫函式,所以我們得借助其它方法。經過研究,發現我們可以通過結合使用system.reflection.emit及system.reflection.assembly裡的類和函式達到我們的目的。為了以後使用方便及實現**的復用,我們可以編寫乙個類。

1) dld類的編寫:

1.開啟專案「test」,開啟類檢視,右擊「tzb」,選擇「新增」-->「類」,類名設定為「dld」,即dynamic loading dll 的每個單詞的開頭字母。

2.新增所需的命名空間及宣告引數傳遞方式列舉:

usingsystem.runtime.interopservices; // 用dllimport 需用此命名空間 

usingsystem.reflection; // 使用assembly 類需用此命名空間

usingsystem.reflection.emit; // 使用ilgenerator 需用此命名空間

3. 在namespace test中,「public class dld」的上面,新增如下**宣告引數傳遞方式列舉:

/// < summary>  

/// 引數傳遞方式列舉,byvalue 表示值傳遞,byref 表示址傳遞

/// < /summary> 

public

enummodepass  

4、在public class dld中,新增如下**:

public

classdld  

/// < summary> 

/// 獲得函式指標 

/// < /summary> 

/// < param name="lpprocname"> 呼叫函式的名稱 < /param> 

public

voidloadfun(stringlpprocname)  

/// < summary> 

/// 解除安裝 dll 

/// < /summary> 

public

voidunloaddll()  

/// < summary> 

/// 呼叫所設定的函式 

/// < /summary> 

/// < param name="objarray_parameter"> 實參 < /param> 

/// < param name="typearray_parametertype"> 實參型別 < /param> 

/// < param name="modepassarray_parameter"> 實參傳送方式 < /param> 

/// < param name="type_return"> 返回型別 < /param> 

/// < returns> 返回所呼叫函式的 object< /returns> 

public

objectinvoke(objectobjarray_parameter, type typearray_parametertype, modepass modepassarray_parameter, type type_return)  

}  if(intptr.size == 4)  

else

if(intptr.size == 8)  

else

il.emitcalli(opcodes.calli, callingconvention.stdcall, type_return, typearray_parametertype);  

il.emit(opcodes.ret); // 返回值 

mymodulebuilder.createglobalfunctions();  

// 取得方法資訊 

methodinfo mymethodinfo = mymodulebuilder.getmethod("myfun"

);  

returnmymethodinfo.invoke(null, objarray_parameter);// 呼叫方法,並返回其值 

}  }

2) dld類的使用:

1.開啟專案「test」,向「form1」窗體中新增乙個按鈕,和乙個testbox,name改為txret。檢視中雙擊按鈕,在「button1_click」方法體上面新增**,建立乙個dld類例項,並進行測試。具體如下:

private

voidbutton1_click(objectsender, eventargs e)  

; // 實參為0 

type parametertypes =newtype ; // 實參型別為int 

modepass themode =newmodepass ; // 傳送方式為值傳

type type_return =typeof(int); // 返回型別為int

ret = (int)mydld.invoke(parameters, parametertypes, themode, type_return);  

txret.text = ret.tostring();  

if(ret != 1)  

if(ret == 1)  

}  

其中,***為要測試的dll名稱,initsdk為dll中的要測試的函式。

至此,c#呼叫dll函式方法就介紹完了,希望對大家有所幫助。

C 呼叫非託管DLL函式

demo region c 捕獲當前螢幕的例子 using system using system.drawing using system.collections using system.componentmodel using system.windows.forms using system...

C 呼叫MATLAB函式 打包dll

選擇library compiler,如圖 在下面files required for your library to runzhong會自動檢測新增函式所依賴的其他函式,在library name中填寫所要生成的dll檔案的名稱,在setting設定儲存位置,如圖 1.首先配置release x6...

C 呼叫DLL庫的方法

1 在c 專案的根目錄下,建立乙個資料夾,叫 thirdparty 在thirdparty裡面新建 include lib 資料夾。include中存放dll庫相關的所有標頭檔案,lib中存放dll庫相關的lib檔案。2 在專案屬性中,vc 目錄 包含目錄 中新增新建的include目錄 3 在專案...