在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic.net讲述的。本文将C#中调用API的要点汇集如下,希望给未在C#中使用过API的朋友一点帮助。另外如果安装了Visual Studio.net的话,在C:\Program Files\Microsoft Visual Studio.NET\FrameworkSDK\Samples\Technologies\Interop\PlatformInvoke\WinAPIs\CS目录下有大量的调用API的例子。 一、调用格式Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  using System.Runtime.InteropServices; //引用此名称空间,简化后面的代码Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  ...Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  //使用DllImportAttribute特性来引入api函数,注意声明的是空方法,即方法体为空。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  [DllImport("user32.dll")]Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  public static extern ReturnType FunctionName(type arg1,type arg2,...);Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  //调用时与调用其他方法并无区别
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  可以使用字段进一步说明特性,用逗号隔开,如:Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  [ DllImport( "kernel32", EntryPoint="GetVersionEx" )]
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  DllImportAttribute特性的公共字段如下:Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  1、CallingConvention 指示向非托管实现传递方法参数时所用的 CallingConvention 值。 Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  CallingConvention.Cdecl : 调用方清理堆栈。它使您能够调用具有 varargs 的函数。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  CallingConvention.StdCall : 被调用方清理堆栈。它是从托管代码调用非托管函数的默认约定。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  2、CharSet 控制调用函数的名称版本及指示如何向方法封送 String 参数。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  此字段被设置为 CharSet 值之一。如果 CharSet 字段设置为Unicode,则所有字符串参数在传递到非托管实现之前都转换成 Unicode 字符。这还导致向 DLL EntryPoint的名称中追加字母“W”。如果此字段设置为 Ansi,则字符串将转换成 ANSI 字符串,同时向 DLL EntryPoint的名称中追加字母“A”。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  大多数 Win32 API 使用这种追加“W”或“A”的约定。如果 CharSet 设置为 Auto,则这种转换就是与平台有关的(在Windows NT 上为 Unicode,在 Windows 98 上为 Ansi)。CharSet 的默认值为 Ansi。CharSet字段也用于确定将从指定的 DLL 导入哪个版本的函数。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  CharSet.Ansi 和 CharSet.Unicode 的名称匹配规则大不相同。对于 Ansi 来说,如果将EntryPoint 设置为“MyMethod”且它存在的话,则返回“MyMethod”。如果 DLL中没有“MyMethod”,但存在“MyMethodA”,则返回“MyMethodA”。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  对于 Unicode 来说则正好相反。如果将 EntryPoint设置为“MyMethod”且它存在的话,则返回“MyMethodW”。如果 DLL中不存在“MyMethodW”,但存在“MyMethod”,则返回“MyMethod”。如果使用的是 Auto,则匹配规则与平台有关(在Windows NT 上为 Unicode,在 Windows 98 上为 Ansi)。如果 ExactSpelling 设置为true,则只有当 DLL 中存在“MyMethod”时才返回“MyMethod”。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  3、EntryPoint 指示要调用的 DLL 入口点的名称或序号。 Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  如果你的方法名不想与api函数同名的话,一定要指定此参数,例如:Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  [DllImport("user32.dll",CharSet="CharSet.Auto",EntryPoint="MessageBox")]Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  public static extern int MsgBox(IntPtr hWnd,string txt,string caption, int type);
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  4、ExactSpelling 指示是否应修改非托管 DLL 中的入口点的名称,以与 CharSet 字段中指定的 CharSet值相对应。如果为 true,则当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Ansi值时,向方法名称中追加字母 A,当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Unicode值时,向方法的名称中追加字母 W。此字段的默认值是 false。 Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  5、PreserveSig 指示托管方法签名不应转换成返回 HRESULT、并且可能有一个对应于返回值的附加 [out, retval] 参数的非托管签名。 Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
  6、SetLastError 指示被调用方在从属性化方法返回之前将调用 Win32 API SetLastError。 true指示调用方将调用 SetLastError,默认为 false。运行时封送拆收器将调用 GetLastError 并缓存返回的值,以防其被其他API 调用重写。用户可通过调用 GetLastWin32Error 来检索错误代码。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM