C#調(diào)用DLL函數(shù)方法(上)
首先,理解托管代碼與非托管代碼的區(qū)別:
1.托管代碼所申請的資源統(tǒng)一由.Net Framework管理,你不用操心,非托管代碼所申請的內(nèi)存等資源則需要你手動去釋放
2.非托管程序運行會很快,是二進制的,托管程序好寫,但是速度就差的很多,資源會用的很多
3.“程序"一般都是在對操作系統(tǒng)進行直接或者間接的操作
"托管程序"是需要通過訪問公共語言運行時(cls)才能訪問操作系統(tǒng)的程序,而“非托管程序”不用通過訪問公共語言運行時(cls)可以直接訪問操作系統(tǒng)的程序
4.vb.net,C#等寫的程序是托管程序,VC++可以寫托管程序,如果用到了內(nèi)存管理,則只能編譯為非托管程序
VC++寫托管的是要用.net的庫,因為我們沒有用.net,所以只用了非托管方式。
(一) C#調(diào)用DLL中的非托管函數(shù)一般方法
首先,應(yīng)該在C#語言源程序中聲明外部方法,其基本形式是:
[DLLImport(“DLL文件”)]
修飾符 extern 返回變量類型 方法名稱 (參數(shù)列表)
其中:
DLL文件:包含定義外部方法的庫文件。
修飾符: 訪問修飾符,除了abstract以外在聲明方法時可以使用的修飾符。
返回變量類型:在DLL文件中你需調(diào)用方法的返回變量類型。
方法名稱:在DLL文件中你需調(diào)用方法的名稱。
參數(shù)列表:在DLL文件中你需調(diào)用方法的列表。
注意:需要在程序聲明中使用System.Runtime.InteropServices命名空間。
DllImport只能放置在方法聲明上。
DLL文件必須位于程序當前目錄或系統(tǒng)定義的查詢路徑中(即:系統(tǒng)環(huán)境變量中Path所設(shè)置的路徑)。
返回變量類型、方法名稱、參數(shù)列表一定要與DLL文件中的定義相一致。
其它可選的 DllImportAttribute 屬性:
CharSet 指示用在入口點中的字符集,如:CharSet=CharSet.Ansi;
SetLastError 指示方法是否保留 Win32"上一錯誤",如:SetLastError=true;
ExactSpelling 指示 EntryPoint 是否必須與指示的入口點的拼寫完全匹配,如:ExactSpelling=false;
PreserveSig指示方法的簽名應(yīng)當被保留還是被轉(zhuǎn)換, 如:PreserveSig=true;
CallingConvention指示入口點的調(diào)用約定, 如:CallingConvention=CallingConvention.Winapi;
此外,關(guān)于“數(shù)據(jù)封送處理”及“封送數(shù)字和邏輯標量”請參閱其它一些文章。
舉例:
New file,選擇visual C# Class。在文件中,創(chuàng)建一個public的類。把待測試的函數(shù)在這個類中作聲明。
- public class ClassName
- {
- [DllImport("xxx.dll", EntryPoint = "xx")]
- public static extern int StartVideo(int nDevNum, int SwitchingChans, IntPtr Main, IntPtr hwndPreview);
- }
Xxx為待測試的dll名稱,xx為dll中提供的方法函數(shù)。若要使用其它函數(shù)名,可以使用EntryPoint屬性設(shè)置。
如何用DllImport調(diào)用DLL中的非托管函數(shù),但是這個是全局的函數(shù),假若DLL中的非托管函數(shù)有一個靜態(tài)變量S,每次調(diào)用這個函數(shù)的時候,靜態(tài)變量S就自動加1。結(jié)果,當需要重新計數(shù)時,就不能得出想要的結(jié)果。所以,要注意啊,用DllImport調(diào)用DLL中的非托管函數(shù)是全局的、靜態(tài)的函數(shù)。
以上介紹的就是C#調(diào)用DLL函數(shù)方法(上),剩下的內(nèi)容將在C#調(diào)用DLL函數(shù)方法(下)中繼續(xù)給大家講解。
【編輯推薦】


















