最近做了個專案用到了vc的dll,但是又需要在.net中調用,研究了下c#調用非託管的dll
先介紹一下dll文件
一.Dll文件
動態連結庫(也稱為DLL,即為「Dynamic Link Library」的縮寫)是Microsoft Windows最重要的組成要素之一,打開Windows系統資料夾,你會發現資料夾中有很多DLL文件,Windows就是將一些主要的系統功能以DLL模組的形式實現。
動態連結函式庫是不能直接執行的,也不能接收訊息,它只是一個獨立的文件,其中包含能被程式或其它DLL呼叫來完成一定操作的函數(方法。註:C#一般稱為「方法」) ,但這些函數不是執行程式本身的一部分,而是根據進程的需要按需載入,此時才能發揮作用。
DLL只有在應用程式需要時才被系統載入到進程的虛擬空間中,成為調用進程的一部分,此時該DLL也只能被該進程的線程訪問,它的句柄可以被調用進程所使用,而調用進程的句柄也可以被該DLL所使用。在記憶體中,一個DLL只有一個實例,而且它的編制與特定的程式語言和編譯器都沒有關係,所以可以透過DLL來實現混合語言程式設計。 DLL函數中的程式碼所建立的任何物件(包括變數)都歸呼叫它的執行緒或行程所有。
二、 DLL的調用
每種程式語言呼叫DLL的方法都不盡相同,在此只對用C#呼叫DLL的方法進行介紹。首先,您需要了解什麼是託管,什麼是非託管。一般可以認為:非託管程式碼主要是基於win 32平台開發的DLL,activeX的元件,託管程式碼是基於.net平台開發的。
(一) 呼叫DLL中的非託管函數一般方法
首先,應該在C#語言原始程式中聲明外部方法,其基本形式是:
[DLLImport(“DLL檔”)]
修飾符extern傳回變數類型方法名稱(參數清單)
其中:
DLL檔案:包含定義外部方法的程式庫檔案。
修飾符:存取修飾符,除了abstract以外在宣告方法時可以使用的修飾符。
返回變數類型:在DLL檔案中你需呼叫方法的返回變數類型。
方法名稱:在DLL檔案中你需呼叫方法的名稱。
參數列表:在DLL檔案中你需呼叫方法的列表。
注意:需要在程式聲明中使用System.Runtime.InteropServices命名空間。
DllImport只能放置在方法聲明上。
DLL檔案必須位於程式目前目錄或系統定義的查詢路徑中(即:系統環境變數中Path設定的路徑)。
傳回變數類型、方法名稱、參數清單一定要與DLL檔案中的定義相符。
若要使用其它函數名,可以使用EntryPoint屬性設置,如:
[DllImport("user32.dll", EntryPoint="MessageBoxA")]
static extern int MsgBox(int hWnd, string msg, string caption, int type);
其它可選的DllImportAttribute屬性:
CharSet指示用在入口點的字元集,如:CharSet=CharSet.Ansi;
SetLastError指示方法是否保留Win32"上一錯誤",如:SetLastError=true;
ExactSpelling指示EntryPoint是否必須與指示的入口點的拼字完全匹配,如:ExactSpelling=false;
PreserveSig指示方法的簽章應保留或轉換,如:PreserveSig=true;
CallingConvention指示入口點的呼叫約定,如:CallingConvention=CallingConvention.Winapi;