c#(winform)環境下使用動態鏈接庫dll的詳解

1,什麼是dll文件?

DLL(Dynamic Link Library)文件爲動態鏈接庫文件,又稱“應用程序拓展”,是軟件文件類型。在Windows中,許多應用程序並不是一個完整的可執行文件,它們被分割成一些相對獨立的動態鏈接庫,即DLL文件,放置於系統中。當我們執行某一個程序時,相應的DLL文件就會被調用。一個應用程序可使用多個DLL文件,一個DLL文件也可能被不同的應用程序使用,這樣的DLL文件被稱爲共享DLL文件。

2,託管dll和非託管dll區別是什麼?

託管DLL就是能夠在公共語言運行庫(Common Language Runtime,簡稱CLR)中能夠直接引用的,並且擴展爲“DLL”的文件。具體所指就是封裝各種命名空間所在的DLL文件,如System.dll等。非託管DLL就是平常所的動態鏈接庫等,其中就包括了封裝所有Windows API函數的DLL文件。各種非託管DLL中的函數在公共語言運行庫中不能直接被調用,而需要經過.Net框架提供的“平臺調用”服務後纔可以。(簡而言之就是.net環境下生成的動態鏈接庫爲託管dll,相反則爲非託管dll

3,託管dll和非託管dll如何使用?

託管dll在VS環境下使用相對容易,可以在項目名上右擊選擇添加應用的方式導入dll,本文這裏不作詳解。非託管dll的使用步驟及如下:

1,需要檢查使用的dll的目標平臺(Any Cpu,x86,x64),在項目屬性生成選項卡中選擇與dll相對應的目標平臺。因爲託管dll是在.net的環境下生成的,轉換爲機器語言後能夠自動識別目標平臺即有框架支持解釋,而非託管不能夠自己識別需要人爲的設置。

2,使用DllImport導入非託管dll。

DllImport會按照以下3種順序查找dll文件:
1)、exe所在目錄;
2)、System32目錄(系統目錄);

3)、環境變量目錄。(即需要將dll及依賴文件放到3個目錄中的任何一個目錄中)。

DllImport的導入規則:
1)、方法名與Win API完全一樣。如果在C#中調用時顯示完全不同的方法名稱,則需要引入EntryPoint屬性,使用別名顯示。
2)、函數除需要DllImport類修飾符外,還需要聲明public static extern類型。
3)、函數返回值和參數必須和調用的API的完全一樣。

4)、必須引入System.Runtime.InteropServices命名空間。

DllImport的可選屬性參數說明:
EntryPoint         指定要調用的 DLL 入口點。 
SetLastError       判斷在執行該方法時是否出錯(使用 Marshal.GetLastWin32Error API 函數來確定)。C#中默認值爲 false。
CharSet            控制名稱及函數中字符串參數的編碼方式。默認值爲 CharSet.Ansi。
ExactSpelling      是否修改入口點以對應不同的字符編碼方式。
CallingConvention  指定用於傳遞方法參數的調用約定。默認值爲 WinAPI。該值對應於基於32位Intel平臺的 __stdcall。
BestFitMapping     是否啓用最佳映射功能,默認爲 true。最佳映射功能提供在沒有匹配項時,自動提供匹配的字符。無法映射的字符通常轉換爲默認的“?”。
PreserveSig        託管方法籤
名是否轉換成返回 HRESULT,默認值爲 true(不應轉換籤名)。並且返回值有一個附加的 [out, retval] 參數的非託管簽名。  

ThrowOnUnmappableChar     控制對轉換爲 ANSI '?' 字符的不可映射的 Unicode 字符引發異常。

4,c#與c++、c動態鏈接庫的參數如何對應?

C C# 備註

short int16 短整型

int int32 整型

long int64 長整型

& ref 取地址

ref 指針

c#中修飾符ref、out的作用及功能

ref 要求參數在傳遞給函數前要初始化,out則不需要,常見於平臺調用中。out和ref傳遞的都是引用而不是值,out側重於輸出使用之前不需賦值而ref在使用之前需要賦值,另外這兩個關鍵字可以變相實現使一個方法輸出多個值。ref可以把參數的數值傳遞進函數,但是out是要把參數清空,就是說你無法把一個數值從out傳遞進去的,out進去後,參數的數值爲空,所以你必須初始化一次。這個就是兩個的區別,或者說就像有的網友說的,ref是有進有出,out是隻出不進。說明是引用的傳遞。

example:

//命名空間

using System.Runtime.InteropServices;

//導入非託管dll

//分配的庫處理和連接到數控指定的IP地址或主機名。

[DllImport("Fwlib64.dll", EntryPoint = "cnc_allclibhndl3", CallingConvention=CallingConvention.Cdecl)]

//short (const char *ipaddr, unsigned short port, long timeout, unsigned short *FlibHndl)

private static extern Int16 cnc_allclibhndl3(ref String ip, UInt16 port, Int64 timeout, ref UInt16 flibHndl);


(整理,源文章來源於網絡)






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章