一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

[C#/C ]C#調(diào)用非托管DLL的APIs - .NET人字拖 - 博客園

 miky 2008-04-07
[C#/C++]C#調(diào)用非托管DLL的APIs 上網(wǎng)baidu一下或google一下這個(gè)東東就有很多人在問(wèn)這個(gè)問(wèn)題,最近我也用到了這個(gè),所以就留下來(lái)以備往后需要是可以查找。我想通過(guò)這個(gè)來(lái)作為C#調(diào)用windows APIs的出發(fā)點(diǎn),在以后的隨筆當(dāng)中介紹一下我現(xiàn)階段用到的一些APIs或非托管類庫(kù)。在調(diào)用非托管DLL的APIs前,我們應(yīng)該好好掌握一下DllImportAttribute,MSDN給出的定義為:可將該屬性應(yīng)用于方法。DllImportAttribute 屬性提供對(duì)從非托管 DLL 導(dǎo)出的函數(shù)進(jìn)行調(diào)用所必需的信息。作為最低要求,必須提供包含入口點(diǎn)的 DLL 的名稱。 1 [DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true, 2 3 CharSet=CharSet.Unicode, ExactSpelling=true, 4 5 CallingConvention=CallingConvention.StdCall)] 6 7 public static extern bool MoveFile(String src, String dst); 8 9 從上面的例子中我們可以看出,從Kernel32.dll中引入這個(gè)API,其中EntryPoint一看就知道是入口點(diǎn),也就是DLL中的函數(shù)名稱。其實(shí)只要用過(guò)VC++的人都知道,Windows APIs中都提供兩個(gè)版本,一個(gè)是W,一個(gè)是A也就是Ansi和Unicode之分,現(xiàn)在一般都采用W,Unicode編程,但是.Net和win32交互的時(shí)候,默認(rèn)是使用CharSet.Ansi來(lái)傳送。在 DllImportAttribute.ExactSpelling 字段為 true 時(shí)(它是 Visual Basic .NET 中的默認(rèn)值),平臺(tái)調(diào)用將只搜索您指定的名稱。例如,如果指定 MessageBox,則平臺(tái)調(diào)用將搜索 MessageBox,如果它找不到完全相同的拼寫(xiě)則失敗。當(dāng) ExactSpelling 字段為 false(它是 C++ 托管擴(kuò)展和 C# 中的默認(rèn)值),平臺(tái)調(diào)用將首先搜索未處理的別名 (MessageBox),如果沒(méi)有找到未處理的別名,則將搜索已處理的名稱 (MessageBoxA)。 由于很多參數(shù)和C#中有所區(qū)別,下面讓我們看看參數(shù)是怎么個(gè)情況: extern “C” __declspec(dllexport) int WINAPI sumAB(int a,int b)這個(gè)和C#中一樣是值類型,a及b的變化不會(huì)對(duì)C#中的參數(shù)造成影響。通過(guò)DllImport表示為: 1 [DllImport(“CppDll.dll")] 2 //返回個(gè)int 類型 3 public static extern int sumAB (int a1,int b1); 下面的是引用類型:也就是說(shuō)a和b的變化直接影響到a1和b1的值。 public static extern int sum (ref int a1,ref int b1); //DLL中申明 extern “C” __declspec(dllexport) int WINAPI sum(int *a,int *b) 同理我們可以得到一下幾種傳值方法:第一種參數(shù)的改變不影響C#中參數(shù)的變化,需要傳入char*類型。 [DllImport(“CppDll.dll")] //傳入值 public static extern int together (string astr,string bstr); //DLL中申明 extern “C” __declspec(dllexport) int WINAPI together(char * stra,char * strb) 當(dāng)我們需要從參數(shù)中傳出char*類型是,那我們就要用到StringBuilder了。 1 // 傳出值 2 public static extern int getParameter (StringBuilder sb1, StringBuilder sb2); 3 //DLL中申明 4 extern “C” __declspec(dllexport) int WINAPI getParameter(char * stra,char * strb) 接著我們先來(lái)看看結(jié)構(gòu)的封送,這里我們要看看StructLayoutAttribute這個(gè)標(biāo)簽,通過(guò)它可以定義自己的格式化類型,在托管代碼中,格式化類型是一個(gè)用StructLayoutAttribute說(shuō)明的結(jié)構(gòu)或類成員,通過(guò)它能夠保證其內(nèi)部成員預(yù)期的布局信息,他的成員說(shuō)明如下: LayoutKind.Automatic 為了提高效率允許運(yùn)行態(tài)對(duì)類型成員重新排序。注意:永遠(yuǎn)不要使用這個(gè)選項(xiàng)來(lái)調(diào)用非托管的動(dòng)態(tài)鏈接庫(kù)函數(shù)。 LayoutKind.Explicit 對(duì)每個(gè)域按照FieldOffset屬性對(duì)類型成員排序 LayoutKind.Sequential 對(duì)出現(xiàn)在托管類型定義地方的非托管內(nèi)存中的類型成員進(jìn)行排序。 我們可以通過(guò)GetSystemInfo來(lái)獲取系統(tǒng)的信息,代碼如下: 1 using System.Runtime.InteropServices; 2 [StructLayout(LayoutKind.Sequential)] 3 public struct SYSTEM_INFO { 4 public uint dwOemId; 5 public uint dwPageSize; 6 public uint lpMinimumApplicationAddress; 7 public uint lpMaximumApplicationAddress; 8 public uint dwActiveProcessorMask; 9 public uint dwNumberOfProcessors; 10 public uint dwProcessorType; 11 public uint dwAllocationGranularity; 12 public uint dwProcessorLevel; 13 public uint dwProcessorRevision; 14 } 15 //調(diào)用 16 [DllImport("kernel32")] 17 static extern void GetSystemInfo(ref SYSTEM_INFO pSI); 18 SYSTEM_INFO pSI = new SYSTEM_INFO(); 19 GetSystemInfo(ref pSI); 當(dāng)我們遇到函數(shù)指針參數(shù)是我們就需要考慮是否要用到回調(diào)函數(shù),例如枚舉所有窗口。 BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARMAM IParam) 我們可以通過(guò)創(chuàng)建一個(gè)代理,它帶有兩個(gè)參數(shù)hwnd和lparam,第一個(gè)參數(shù)是一個(gè)窗口句柄,第二個(gè)參數(shù)由應(yīng)用程序定義,兩個(gè)參數(shù)均為整形。當(dāng)這個(gè)回調(diào)函數(shù)返回一個(gè)非零值時(shí),標(biāo)示執(zhí)行成功,零則暗示失敗,這個(gè)例子總是返回True值,以便持續(xù)枚舉。最后創(chuàng)建以代理對(duì)象(delegate),并把它作為一個(gè)參數(shù)傳遞給EnumWindows 函數(shù),平臺(tái)會(huì)自動(dòng)地 把代理對(duì)象轉(zhuǎn)化成函數(shù)能夠識(shí)別的回調(diào)格式。 1 using System; 2 using System.Runtime.InteropServices; 3 public delegate bool CallBack(int hwnd, int lParam); 4 public class EnumReportApp { 5 [DllImport("user32")] 6 public static extern int EnumWindows(CallBack x, int y); 7 public static void Main() 8 { 9 CallBack myCallBack = new CallBack(EnumReportApp.Report); 10 EnumWindows(myCallBack, 0); 11 } 12 public static bool Report(int hwnd, int lParam) { 13 Console.Write("窗口句柄為"); 14 Console.WriteLine(hwnd); 15 return true; 16 } 17 } OK,如果熟悉了以上方方面面,基本上也能夠調(diào)用APIs了別忘了P/Invoke能夠幫上很大的忙,我們可以去wiki網(wǎng)站查詢我們所要的API:http://。還需要說(shuō)明的是很多例子等都來(lái)自MSDN和網(wǎng)上檢索得到的?。?!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    99久久免费中文字幕| 国产又粗又长又大的视频| 亚洲欧美日本国产不卡| 精品女同在线一区二区| 日本午夜乱色视频在线观看| 日本一区不卡在线观看| 特黄大片性高水多欧美一级 | 69久久精品亚洲一区二区| 亚洲性生活一区二区三区| 日韩欧美国产精品自拍| 高清欧美大片免费在线观看| 色综合久久中文综合网| 欧美一区二区黑人在线| 一本色道久久综合狠狠躁| 国产免费观看一区二区| 九九热精品视频免费在线播放| 日韩18一区二区三区| 日韩精品少妇人妻一区二区| 亚洲综合精品天堂夜夜| 欧美高潮喷吹一区二区| 国产在线观看不卡一区二区| 中国一区二区三区人妻| 国产成人精品资源在线观看| 日本国产欧美精品视频| 久久综合狠狠综合久久综合| 激情五月天深爱丁香婷婷| 亚洲综合一区二区三区在线| 日本午夜免费福利视频| 国产中文字幕一二三区| 久久精品国产一区久久久| 欧美黑人在线一区二区| av一区二区三区天堂| 亚洲乱码av中文一区二区三区| 国产日产欧美精品视频| 亚洲熟妇熟女久久精品| 亚洲欧美黑人一区二区| 丝袜诱惑一区二区三区| 日本少妇aa特黄大片| 中文字幕一区二区三区大片| 日本男人女人干逼视频| 九九热视频网在线观看|