C#調(diào)用windows api的要點
來源:易賢網(wǎng) 閱讀:1066 次 日期:2015-02-06 15:24:05
溫馨提示:易賢網(wǎng)小編為您整理了“C#調(diào)用windows api的要點”,方便廣大網(wǎng)友查閱!

在.Net Framework SDK文檔中,關于調(diào)用Windows API的指示比較零散,并且其中稍全面一點的是針對Visual Basic .net講述的。本文將C#中調(diào)用API的要點匯集如下,希望給未在C#中使用過API的朋友一點幫助。另外如果安裝了Visual Studio .net的話,在C:/Program Files/Microsoft Visual Studio .NET/FrameworkSDK/Samples/Technologies/Interop/PlatformInvoke/WinAPIs/CS目錄下有大量的調(diào)用API的例子。

一、調(diào)用格式

using System.Runtime.InteropServices; //引用此名稱空間,簡化后面的代碼

...

//使用DllImportAttribute特性來引入api函數(shù),注意聲明的是空方法,即方法體為空。

[DllImport("user32.dll")]

public static extern ReturnType FunctionName(type arg1,type arg2,...);

//調(diào)用時候與調(diào)用其他方法并無區(qū)別

DllImportAttribute特性的公共字段如下:

1、CallingConvention 指示向非托管實現(xiàn)傳遞方法參數(shù)時所用的 CallingConvention 值。

CallingConvention.Cdecl : 調(diào)用方清理堆棧。它使您能夠調(diào)用具有 varargs 的函數(shù)。

CallingConvention.StdCall : 被調(diào)用方清理堆棧。它是從托管代碼調(diào)用非托管函數(shù)的默認約定。

2、CharSet 控制調(diào)用函數(shù)的名稱版本及指示如何向方法封送 String 參數(shù)。

此字段被設置為 CharSet 值之一。如果 CharSet 字段設置為 Unicode,則所有字符串參數(shù)在傳遞到非托管實現(xiàn)之前都轉換成 Unicode 字符。這還導致向 DLL EntryPoint 的名稱中追加字母“W”。如果此字段設置為 Ansi,則字符串將轉換成 ANSI 字符串,同時向 DLL EntryPoint 的名稱中追加字母“A”。大多數(shù) Win32 API 使用這種追加“W”或“A”的約定。如果 CharSet 設置為 Auto,則這種轉換就是與平臺有關的(在 Windows NT 上為 Unicode,在 Windows 98 上為 Ansi)。CharSet 的默認值為 Ansi。CharSet 字段也用于確定將從指定的 DLL 導入哪個版本的函數(shù)。CharSet.Ansi 和 CharSet.Unicode 的名稱匹配規(guī)則大不相同。對于 Ansi 來說,如果將 EntryPoint 設置為“MyMethod”且它存在的話,則返回“MyMethod”。如果 DLL 中沒有“MyMethod”,但存在“MyMethodA”,則返回“MyMethodA”。對于 Unicode 來說則正好相反。如果將 EntryPoint 設置為“MyMethod”且它存在的話,則返回“MyMethodW”。如果 DLL 中不存在“MyMethodW”,但存在“MyMethod”,則返回“MyMethod”。如果使用的是 Auto,則匹配規(guī)則與平臺有關(在 Windows NT 上為 Unicode,在 Windows 98 上為 Ansi)。如果 ExactSpelling 設置為 true,則只有當 DLL 中存在“MyMethod”時才返回“MyMethod”。

3、EntryPoint 指示要調(diào)用的 DLL 入口點的名稱或序號。

如果你的方法名不想與api函數(shù)同名的話,一定要指定此參數(shù),例如:

[DllImport("user32.dll",CharSet="CharSet.Auto",EntryPoint="MessageBox")]

public static extern int MsgBox(IntPtr hWnd,string txt,string caption, int type);

4、ExactSpelling 指示是否應修改非托管 DLL 中的入口點的名稱,以與 CharSet 字段中指定的 CharSet 值相對應。如果為 true,則當 DllImportAttribute.CharSet 字段設置為 CharSet 的 Ansi 值時,向方法名稱中追加字母 A,當 DllImportAttribute.CharSet 字段設置為 CharSet 的 Unicode 值時,向方法的名稱中追加字母 W。此字段的默認值是 false。

5、PreserveSig 指示托管方法簽名不應轉換成返回 HRESULT、并且可能有一個對應于返回值的附加 [out, retval] 參數(shù)的非托管簽名。

6、SetLastError 指示被調(diào)用方在從屬性化方法返回之前將調(diào)用 Win32 API SetLastError。 true 指示調(diào)用方將調(diào)用 SetLastError,默認為 false。運行時封送拆收器將調(diào)用 GetLastError 并緩存返回的值,以防其被其他 API 調(diào)用重寫。用戶可通過調(diào)用 GetLastWin32Error 來檢索錯誤代碼。

二、參數(shù)類型:

1、數(shù)值型直接用對應的就可。

2、字符串指針(api) -> string (.net)

3、句柄 (dWord) -> IntPtr

4、結構 -> 結構或者類

這種情況下,要先用StructLayout特性限定聲明,例如:

// declared as class

[ StructLayout( LayoutKind.Sequential )]

public class OSVersionInfo

{

public int OSVersionInfoSize;

public int majorVersion;

public int minorVersion;

public int buildNumber;

public int platformId;

[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]

public String versionString;

}

// declared as struct

[ StructLayout( LayoutKind.Sequential )]

public struct OSVersionInfo2

{

public int OSVersionInfoSize;

public int majorVersion;

public int minorVersion;

public int buildNumber;

public int platformId;

[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]

public String versionString;

}

MashalAs特性:用于描述字段、方法或參數(shù)的封送處理格式。特性作為參數(shù)前綴并指定目標需要的數(shù)據(jù)類型。例如,以下代碼將兩個參數(shù)作為數(shù)據(jù)類型長指針封送給 Windows API 函數(shù)的字符串 (LPStr):

[MarshalAs(UnmanagedType.LPStr)]

String existingfile;

[MarshalAs(UnmanagedType.LPStr)]

String newfile;

注意結構作為參數(shù)時候,一般前面要加上ref修飾符,否則會出現(xiàn)錯誤:對象的引用沒有指定對象的實例。

[ DllImport( "kernel32", EntryPoint="GetVersionEx" )]

public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi );

三、如果在調(diào)用平臺 invoke 后的任何位置都未引用托管對象,則垃圾回收器可能將完成該托管對象。這將釋放資源并使句柄無效,從而導致平臺 invoke 調(diào)用失敗。用 HandleRef 包裝句柄可保證在平臺 invoke 調(diào)用完成前,不對托管對象進行垃圾回收。

更多信息請查看IT技術專欄

更多信息請查看數(shù)據(jù)庫
易賢網(wǎng)手機網(wǎng)站地址:C#調(diào)用windows api的要點
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢?yōu)闇剩?/div>

2025國考·省考課程試聽報名

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網(wǎng)