原文地址:http://www.codeproject.com/Articles/9714/Win32-API-C-to-NET
.NET 调用 API 声明格式
VB.NET
Declare Function <Name> Lib <dll name> <Optional fields> (<params>) As <return type>' Example:Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA"(_ ByVal dwFlags As Integer, ByRef lpSource As Object, _ ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, _ ByVal lpBuffer As String, ByVal nSize As Integer, _ ByRef Arguments As Integer) As Integer
C#
[DllImport("<dll name>", <optional fields>)]static extern <return type> <Method name>(<Params>)[DllImport("kernel32.dll", SetLastError=true)]// Example:static extern int FormatMessageA(int dwFlags, ref object lpSource, int dwMessageId, int dwLanguageId, string lpBuffer, int nSize, ref int Arguments)
Managed C++ .NET
[DllImport("<Dll name>",<optional fields>)] static <return type> <Function name>( <Params>);// Example:[DllImport("KERNEL32.DLL",EntryPoint="MoveFileW", SetLastError=true,CharSet=CharSet::Unicode,ExactSpelling=true, CallingConvention=CallingConvention::StdCall)]static bool MoveFile(String^ src, String^ dst);
数据类型转换表: C++ 到 .NET
类型 | .NET | C++ | ATOM | ushorttypedef WORD ATOM;BOOL | bool, inttypedef int BOOL;BOOLEAN | bool, bytetypedef BYTE BOOLEAN;BYTE | bytetypedef unsigned char BYTE;CALLBACK | delegate#define CALLBACK __stdcallCHAR | chartypedef char CHAR;COLORREF | uinttypedef DWORD COLORREF;CONST | const#define CONST constDWORD | uinttypedef unsigned long DWORD;DWORDLONG | ulongtypedef ULONGLONG DWORDLONG;DWORD_PTR DWORD * | uint, IntPtrtypedef ULONG_PTR DWORD_PTR;DWORD32 | uinttypedef unsigned int DWORD32;DWORD64 | ulongtypedef unsigned __int64 DWORD64;FLOAT | singletypedef float FLOAT;HACCEL | IntPtrtypedef HANDLE HACCEL;HANDLE | IntPtrtypedef PVOID HANDLE;HBITMAP | IntPtrtypedef HANDLE HBITMAP;HBRUSH | IntPtrtypedef HANDLE HBRUSH;HCOLORSPACE | IntPtrif(WINVER >= 0x0400)
typedef HANDLE HCOLORSPACE;HCONV | IntPtrtypedef HANDLE HCONV;HCONVLIST | IntPtrtypedef HANDLE HCONVLIST;HCURSOR | IntPtrtypedef HICON HCURSOR;HDC | IntPtrtypedef HANDLE HDC;HDDEDATA | IntPtrtypedef HANDLE HDDEDATA;HDESK | IntPtrtypedef HANDLE HDESK;HDROP | IntPtrtypedef HANDLE HDROP;HDWP | IntPtrtypedef HANDLE HDWP;HENHMETAFILE | IntPtrtypedef HANDLE HENHMETAFILE;HFILE | inttypedef int HFILE;HFONT | IntPtrtypedef HANDLE HFONT;HGDIOBJ | IntPtrtypedef HANDLE HGDIOBJ;HGLOBAL | IntPtrtypedef HANDLE HGLOBAL;HHOOK | IntPtrtypedef HANDLE HHOOK;HICON | IntPtrtypedef HANDLE HICON;HINSTANCE | IntPtrtypedef HANDLE HINSTANCE;HKEY | IntPtrtypedef HANDLE HKEY;HKL | IntPtrtypedef HANDLE HKL;HLOCAL | IntPtrtypedef HANDLE HLOCAL;HMENU | IntPtrtypedef HANDLE HMENU;HMETAFILE | IntPtrtypedef HANDLE HMETAFILE;HMODULE | IntPtrtypedef HINSTANCE HMODULE;HMONITOR | IntPtrif(WINVER >= 0x0500)
typedef HANDLE HMONITOR;
HPALETTE | IntPtrtypedef HANDLE HPALETTE;HPEN | IntPtrtypedef HANDLE HPEN;HRESULT | int, uinttypedef LONG HRESULT;HRGN | IntPtrtypedef HANDLE HRGN;HRSRC | IntPtrtypedef HANDLE HRSRC;HSZ | IntPtrtypedef HANDLE HSZ;HWINSTA | IntPtrtypedef HANDLE WINSTA;HWND | IntPtrtypedef HANDLE HWND;INT | inttypedef int INT;INT_PTR | IntPtr#if defined(_WIN64)
typedef __int64 INT_PTR;
#else
typedef int INT_PTR;
INT32 | inttypedef signed int INT32;INT64 | longtypedef signed __int64 INT64;LANGID | ushort, inttypedef WORD LANGID;LCID | uinttypedef DWORD LCID;LCTYPE | uinttypedef DWORD LCTYPE;LGRPID | uinttypedef DWORD LGRPID;LONG | inttypedef long LONG;LONGLONG | long#if !defined(_M_IX86)
typedef __int64 LONGLONG;
#else
typedef double LONGLONG;
LONG_PTR | IntPtr#if defined(_WIN64)
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
LONG32 | inttypedef signed int LONG32;LONG64 | longtypedef __int64 LONG64;LPARAM | IntPtrtypedef LONG_PTR LPARAM;LPBOOL Bool * | IntPtr, booltypedef BOOL *LPBOOL;LPBYTE Byte * | IntPtr, bytetypedef BYTE *LPBYTE;LPCOLORREF | IntPtr, uinttypedef DWORD *LPCOLORREF;LPCSTR | string, IntPtr, StringBuildertypedef CONST CHAR *LPCSTR;LPCTSTR | string, IntPtr, StringBuilder#ifdef UNICODE
typedef LPCWSTR LPCTSTR;
#else
typedef LPCSTR LPCTSTR;
LPCVOID | IntPtrtypedef CONST void *LPCVOID;LPCWSTR | string, IntPtr, StringBuildertypedef CONST WCHAR *LPCWSTR;LPDWORD | IntPtr, uinttypedef DWORD *LPDWORD;LPHANDLE | IntPtrtypedef HANDLE *LPHANDLE;LPINT | IntPtr, inttypedef int *LPINT;LPLONG | IntPtr, inttypedef long *LPLONG;LPSTR | string, IntPtr, StringBuildertypedef CHAR *LPSTR;LPTSTR | string, IntPtr, StringBuilder#ifdef UNICODE
typedef LPWSTR LPTSTR;
#else
typedef LPSTR LPTSTR;
LPVOID | IntPtrtypedef void *LPVOID;LPWORD | IntPtr, ushorttypedef WORD *LPWORD;LPWSTR | string, IntPtr, StringBuildertypedef WCHAR *LPWSTR;LRESULT | IntPtr, inttypedef LONG_PTR LRESULT;PBOOL | IntPtr, booltypedef BOOL *PBOOL;PBOOLEAN | IntPtr, booltypedef BOOLEAN *PBOOLEAN;PBYTE | IntPtr, bytetypedef BYTE *PBYTE;PCHAR | IntPtr, chartypedef CHAR *PCHAR;PCSTR | string, IntPtr, StringBuildertypedef CONST CHAR *PCSTR;PCTSTR | string, IntPtr, StringBuilder#ifdef UNICODE
typedef LPCWSTR PCTSTR;
#else
typedef LPCSTR PCTSTR;
PCWSTR | string, IntPtr, StringBuildertypedef CONST WCHAR *PCWSTR;PDWORD | IntPtr, uinttypedef DWORD *PDWORD;PDWORDLONG | IntPtr, ulongtypedef DWORDLONG *PDWORDLONG;PDWORD_PTR | IntPtr, uinttypedef DWORD_PTR *PDWORD_PTR;PDWORD32 | IntPtr, uinttypedef DWORD32 *PDWORD32;PDWORD64 | IntPtr, ulongtypedef DWORD64 *PDWORD64;PFLOAT | IntPtr, singletypedef FLOAT *PFLOAT;PHANDLE | IntPtrtypedef HANDLE *PHANDLE;PHKEY | IntPtrtypedef HKEY *PHKEY;PINT | IntPtr, inttypedef int *PINT;PINT_PTR | IntPtrtypedef INT_PTR *PINT_PTR;PINT32 | IntPtr, inttypedef INT32 *PINT32;PINT64 | IntPtr, longtypedef INT64 *PINT64;PLCID | IntPtr, uinttypedef PDWORD PLCID;PLONG | IntPtr, inttypedef LONG *PLONG;PLONGLONG | IntPtr, longtypedef LONGLONG *PLONGLONG;PLONG_PTR | IntPtr, inttypedef LONG_PTR *PLONG_PTR;PLONG32 | IntPtr, inttypedef LONG32 *PLONG32;PLONG64 | IntPtr, longtypedef LONG64 *PLONG64;POINTER_32 | IntPtr, int#if defined(_WIN64)
#define POINTER_32 __ptr32
#else
#define POINTER32
POINTER_64 | IntPtr, long#define POINTER_64 __ptr64PSHORT | IntPtr, shorttypedef SHORT *PSHORT;PSIZE_T | IntPtrtypedef SIZE_T *PSIZE_T;PSSIZE_T | IntPtrtypedef SSIZE_T *PSSIZE_T;PSTR | IntPtr, string, StringBuildertypedef CHAR *PSTR;PTBYTE | IntPtr, chartypedef TBYTE *PTBYTE;PTCHAR | IntPtr, string, StringBuildertypedef TCHAR *PTCHAR;PTSTR | IntPtr, string, StringBuilder#ifdef UNICODE
typedef LPWSTR PTSTR;
#else
typedef LPSTR PTSTR;
PUCHAR | IntPtr, string, StringBuildertypedef UCHAR *PUCHAR;PUINT | IntPtr, uinttypedef UINT *PUINT;PUINT_PTR | IntPtr, uinttypedef UINT_PTR *PUINT_PTR;PUINT32 | IntPtr, uinttypedef UINT32 *PUINT32;PUINT64 | IntPtr, ulongtypedef UINT64 *PUINT64;PULONG | IntPtr, uinttypedef ULONG *PULONG;PULONGLONG | IntPtr, ulongtypedef ULONGLONG *PULONGLONG;PULONG_PTR | IntPtr, uint:typedef ULONG_PTR *PULONG_PTR;PULONG32 | IntPtr, uinttypedef ULONG32 *PULONG32;PULONG64 | IntPtr, ulongtypedef ULONG64 *PULONG64;PUSHORT | IntPtr, ushorttypedef USHORT *PUSHORT;PVOID | IntPtrtypedef void *PVOID;PWCHAR | IntPtr, stringtypedef WCHAR *PWCHAR;PWORD | IntPtr, ushorttypedef WORD *PWORD;PWSTR | IntPtr, string, StringBuildertypedef WCHAR *PWSTR;SC_HANDLE | IntPtrtypedef HANDLE SC_HANDLE;SC_LOCK | IntPtrtypedef LPVOID SC_LOCK;SERVICE_STATUS_HANDLE | IntPtrtypedef HANDLE SERVICE_STATUS_HANDLE;SHORT | shorttypedef short SHORT;SIZE_T | uint, IntPtrtypedef ULONG_PTR SIZE_T;SSIZE_T | int, IntPtrtypedef LONG_PTR SSIZE_T;TBYTE | char#ifdef UNICODE
typedef WCHAR TBYTE;
#else
typedef unsigned char TBYTE;
TCHAR | char#ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
UCHAR | chartypedef unsigned char UCHAR;UINT | uinttypedef unsigned int UINT;UINT_PTR | UIntPtr, uint#if defined(_WIN64)
typedef unsigned __int64 UINT_PTR;
#else
typedef unsigned int UINT_PTR;
UINT32 | uinttypedef unsigned int UINT32;
UINT64 | ulongtypedef usigned __int64 UINT64;
ULONG | uinttypedef unsigned long ULONG;ULONGLONG | ulong#if !defined(_M_IX86)
typedef unsigned __int64 ULONGLONG;
#else
typedef double ULONGLONG
ULONG_PTR | IntPtr, uint#if defined(_WIN64)
typedef unsigned __int64 ULONG_PTR;
#else
typedef unsigned long ULONG_PTR;
ULONG32 | uinttypedef unsigned int ULONG32;ULONG64 | ulongtypedef unsigned __int64 ULONG64;USHORT | ushorttypedef unsigned short USHORT;USN | longtypedef LONGLONG USN;VOID | void#define VOID voidWCHAR | chartypedef wchar_t WCHAR;WINAPI | 参见 CallingConvention 枚举#define WINAPI __stdcallWORD | ushorttypedef unsigned short WORD;WPARAM | IntPtr, uinttypedef UINT_PTR WPARAM;
提示
- 列表中指向某一类型的指针使用前缀表示,例如: DWORD* = PDWORD
- 某些类型(例如: UIntPtr)不兼容 CLS,所以使用了 IntPtr,你可以根据你实际的情况进行选择
- 通常在 IDE 中输入“=”号后Intellisense自动弹出的类型是最好的选择
- 在 COM Interop 中使用字符串时,应当总是使用 WCHAR*,TCHAR* 等等来作为输入;使用 string 或 StringBuilder 作为输出。当你用一个 IntPtr 通过 Marshal.PtrToStructure() 方法来提取所有字符时会需要递增指针,可以使用 pointer +=Marshal.SizeOf(<last object you got back>);
- 有时数据类型并不需要完全一致,譬如 int 可以用来替换 uint
- 需要把 IntPtr 转换为 int 或其他类的时候,应使用 Marshal.PtrToStructure() 或IntPtr 的成员方法
- 如果你使用的 API 建立在 ANSI 或 Unicode 的基础上,首先应确保选择了正确的API。参见: CharSet 枚举
- 大多数的 API 可以写成托管类型的声明,但某些需要指针,在 C# 中使用 unsafe 关键字你就能使用指针,另外编译时记得带上 /unsafe 开关
- 如果想确保 gc 不回收API 调用时使用的 IntPtr,你可以使用 HandleRef 类型
- 当需要为API定义一个结构时,确保他们带上 StructLayout.Sequential 属性
- 使用 API 方法传入/传出数组时,先确认是一个指向数组的指针还是一个数组对象,如果是指针你需要先把它转成 IntPtr
- 列表中多使用 IntPtr 来提取某个类型,有时你可以直接用 ref <datatype> 或 out <datatype>的形式,但是对于char* 你还是要用IntPr 作为输入,用 ref IntPtr 作为输出
- 当你定义的函数无法正常工作,并不一定是你的函数定义写错了,这有可能是传入了错误的数据或其他原因
- 仅在必要时使用 Marshal 及 MarshalAs,某些场合下他们消耗较多的处理时间