c# 調(diào)用dll的幾種方式
一、什么叫動態(tài)鏈接庫?
動態(tài)鏈接庫(也稱為dll,即為“Dynamic Link Library”的縮寫),是Microsoft Windows最重要的組成要素之一,Windows系統(tǒng)文件夾中就存在很多DLL文件,Windows就是將一些主要的系統(tǒng)功能以DLL模塊的形式實現(xiàn)。
動態(tài)鏈接庫是不能直接執(zhí)行的,也不能接收消息,他是一個獨(dú)立的文件,DLL 文件通常包含函數(shù)、類、變量和其他資源,可以被程序動態(tài)加載并調(diào)用。
DLL只有在應(yīng)用程序需要時才被系統(tǒng)加載到進(jìn)程的虛擬空間中,成為調(diào)用進(jìn)程的一部分,此時該DLL也只能被該進(jìn)程的線程訪問,它的句柄可以被調(diào)用進(jìn)程所使用,而調(diào)用進(jìn)程的句柄也可以被該DLL所使用。在內(nèi)存中,一個DLL只有一個實例,且它的編制與具體的編程語言和編譯器都沒有關(guān)系,所以可以通過DLL來實現(xiàn)混合語言編程。DLL函數(shù)中的代碼所創(chuàng)建的任何對象(包括變量)都?xì)w調(diào)用它的線程或進(jìn)程所有。
通過使用 DLL,程序可以在運(yùn)行時動態(tài)鏈接到需要的函數(shù)或資源,而不需要將所有功能都靜態(tài)地包含在可執(zhí)行文件中。這樣可以減少程序的內(nèi)存占用,提高系統(tǒng)的效率。此外,當(dāng)需要更新某個功能時,只需替換 DLL 文件而不必修改整個程序。
二、使用DLL優(yōu)點(diǎn):
1.使用較少的資源
2.推廣模塊式體系結(jié)構(gòu)
3.簡化安裝和部署
三、DLL調(diào)用
1.使用DllImport特性:
這是用于調(diào)用非托管 DLL 的一種方式。你需要聲明一個靜態(tài) extern 方法,在方法上應(yīng)用 DllImport
特性指定 DLL 文件的名稱。這種方式適用于調(diào)用其他語言(例如C++)書寫的dll。
首先,應(yīng)該在C#語言源程序中聲明外部方法,其基本形式是:
[DllImport("DLL文件")]
修飾符 extern 返回變量類型 方法名稱(參數(shù)列表)
using System; using System.Runtime.InteropServices; class Program { [DllImport("YourDllName.dll")] public static extern void YourFunctionName(); }
注意:需要在程序聲明中使用System.Runtime.InteropServices命名空間。
- DllImport只能放置在方法聲明上。
- DLL文件必須位于程序當(dāng)前目錄或系統(tǒng)定義的查詢路徑中(即:系統(tǒng)環(huán)境變量中Path所設(shè)置的路徑)。
- 返回變量類型、方法名稱、參數(shù)列表一定要與DLL文件中的定義相一致。
- 若要使用其它函數(shù)名,可以使用EntryPoint屬性設(shè)置,如:
[DllImport("user32.dll", EntryPoint="MessageBoxA")] static extern int MsgBox(int hWnd, string msg, string caption, int type);
若要設(shè)置字符格式,可以使用CharSet = CharSet.Unicode如:
[DllImport("cbbofspecmedia.dll",CharSet = CharSet.Unicode)] public static extern int nGetSpecMediaInfoParseExp(byte[] filePath, ExportCbbCallback callback);
通常,c++ dll庫字符編碼方式都為utf-8,c#調(diào)用dll時,若遇到中文字符的接收與傳遞,會出現(xiàn)中文字符顯示亂碼與無法傳遞。
由于.NET平臺多采用Unicode字符集,可能為gb2312,utf-16等;若此時對接收到的參數(shù),做utf-8到Unicode的轉(zhuǎn)換,仍不能得到正確結(jié)果;同樣,對參數(shù)進(jìn)行Unicode到utf-8的轉(zhuǎn)換,也不能正確傳遞數(shù)據(jù)。
原因在于從dll獲取到的char已經(jīng)隱式轉(zhuǎn)換成為了string,由于utf-8與Unicode漢字編碼字節(jié)數(shù)的不一致,導(dǎo)致隱式轉(zhuǎn)換出錯,之后再進(jìn)行轉(zhuǎn)換便不能得到正確結(jié)果。
解決辦法:
在C#中,將string,轉(zhuǎn)為byte[] 傳給dll,(因為string就是一個byte[])。
string path = @"D:\workingDocument\視頻\video.mp4"; Byte[] bytePath = Encoding.UTF8.GetBytes(path); int v = cbb.nGetSpecMediaInfoParseExp(bytePath, (a,b)=>{ int aa = a; string bb = b; });
2.調(diào)用托管的DLL
C#調(diào)用托管DLL是很簡單的,(一般適用于C#語言書寫的dll)。右鍵點(diǎn)擊項目 -> 添加 -> 引用 -> 瀏覽,選擇你要添加的 DLL 文件。然后在代碼中直接調(diào)用 DLL 中的方法即可,最后需要用using導(dǎo)入相關(guān)的命名空間。
到此這篇關(guān)于c# 調(diào)用dll的幾種方式的文章就介紹到這了,更多相關(guān)c# 調(diào)用dll內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解析c#在未出現(xiàn)異常情況下查看當(dāng)前調(diào)用堆棧的解決方法
本篇文章是對c#在未出現(xiàn)異常情況下查看當(dāng)前調(diào)用堆棧的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C#實現(xiàn)讀取匿名對象屬性值的方法示例總結(jié)
這篇文章主要介紹了C#實現(xiàn)讀取匿名對象屬性值的方法,結(jié)合實例形式總結(jié)分析了C#通過反射、轉(zhuǎn)換等方法讀取匿名對象屬性值的相關(guān)操作技巧,需要的朋友可以參考下2020-03-03C#爬蟲基礎(chǔ)之HttpClient獲取HTTP請求與響應(yīng)
這篇文章介紹了C#使用HttpClient獲取HTTP請求與響應(yīng)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05C#實現(xiàn)JSON和對象之間互相轉(zhuǎn)換功能示例
這篇文章主要介紹了C#實現(xiàn)JSON和對象之間互相轉(zhuǎn)換功能,結(jié)合實例形式較為詳細(xì)的分析了C#實現(xiàn)對象與json之間相互轉(zhuǎn)換的操作技巧,需要的朋友可以參考下2017-09-09C#中TreeView節(jié)點(diǎn)的自定義繪制方法
這篇文章主要介紹了C#中TreeView節(jié)點(diǎn)的自定義繪制方法,實例展示了TreeView節(jié)點(diǎn)的操作技巧,需要的朋友可以參考下2015-02-02