本文的內容接著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 需用此命名空間3. 在namespace test中,「public class dld」的上面,新增如下**宣告引數傳遞方式列舉:usingsystem.reflection; // 使用assembly 類需用此命名空間
usingsystem.reflection.emit; // 使用ilgenerator 需用此命名空間
/// < summary>4、在public class dld中,新增如下**:/// 引數傳遞方式列舉,byvalue 表示值傳遞,byref 表示址傳遞
/// < /summary>
public
enummodepass
public2) dld類的使用: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);// 呼叫方法,並返回其值
} }
1.開啟專案「test」,向「form1」窗體中新增乙個按鈕,和乙個testbox,name改為txret。檢視中雙擊按鈕,在「button1_click」方法體上面新增**,建立乙個dld類例項,並進行測試。具體如下:
private其中,***為要測試的dll名稱,initsdk為dll中的要測試的函式。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)
}
至此,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 在專案...