65.9K
CodeProject 正在变化。 阅读更多。
Home

Win32 API:C++ 到 .NET

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.77/5 (40投票s)

2005年3月1日

12分钟阅读

viewsIcon

412231

这是一份将 C++ API 调用转换为 .NET P/Invoke 的对照表。它包括数据类型转换和一些技巧。

引言

我正在撰写一篇文章,为那些需要在 .NET 程序中使用 API 导入来调用 C++ 函数的开发人员提供参考。我还没有找到一个看起来很好或者包含所有数据类型并正确转换的完整网站。所以,我决定自己写一个。我还建议,如果可用的话,使用任何与 API 功能相同的新的 .NET 函数。至少 75% 的 API 已经被转换为 .NET,并可在各种类中使用。这是因为它们通常工作得更好看,也更美观。如果您有任何问题,请给我发送电子邮件或发布到留言板上。

.NET API 声明形式

VB.NET

Declare Function <Name> Lib <dll name> <Optional fields> (<params>) _
                                                      As <return type>

C# 定义

[DllImport("<dll name>", <optional fields>)] 
        static extern <return type> <Method name> (<Params>)

托管 C++ .NET

[DllImport("<Dll name>",<optional fields>)]
     static <return type> <Function name>( <Params>);

示例

C#、VB.NET 和 VB6 的 Windows API 参考 - 该网站包含 VB.NET、C#.NET 和一些 VB6 的所有主要 API 声明。

这是我使用这些网站制作的一个程序

VB.NET

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("kernel32.dll", SetLastError=true)] 
   static extern int FormatMessageA ( int dwFlags, ref object lpSource, 
   int dwMessageId, int dwLanguageId, string lpBuffer, 
   int nSize, ref int Arguments)

托管 C++. NET

[DllImport("KERNEL32.DLL",EntryPoint="MoveFileW",
   SetLastError=true,CharSet=CharSet::Unicode,ExactSpelling=true,
   CallingConvention=CallingConvention::StdCall)]
   static bool MoveFile( String^ src, String^ dst );

技巧

  1. 在此列表中,数据类型的指针表示为 P,例如 DWORD* = PDWORD
  2. 某些类型(如 UIntPtr)不符合 CLS 规范,因此我使用 IntPtr 代替,但您可以使用其中任何一种。
  3. 通常,IDE 的 Intellisense 中“=”后出现的第一个选项是最佳选择。
  4. 在 COM Interop 中使用字符串时,对于输入,您总是使用 string 来表示 WCHAR*TCHAR* 等。对于输出,您可以使用 stringStringBuilder,但有时您需要使用 IntPtr 并使用 Marshal.PtrToStructure() 从中封送字符,并递增指针直到遇到 null 字符。要递增指针,请将其转换为 int,并每次按从 Marshal.PtrToStructure() 获取的类型大小递增。例如:pointer += Marshal.SizeOf(<上次获取的对象>);
  5. 有时某些不正确的数据类型也会起作用。例如:int 可以用于 uint
  6. 如果您需要将 IntPtr 转换回 int 或其他类,请使用 Marshal.PtrToStructure() 或其他 IntPtr 方法。
  7. 如果您使用的 API 依赖于 ANSI 或 Unicode,请确保选择正确的选项,以便正确格式化字符串。请查看 CharSet 枚举。
  8. 大多数 API 调用都可以用托管声明编写,但有些需要指针。在 C# 中,如果将代码用 unsafe 关键字括起来并使用 /unsafe 编译器选项,则可以使用指针。
  9. 如果您想确保垃圾收集器不会在 API 调用中吞噬您的 IntPtr,您可以使用 HandleRef 类型。
  10. 当您需要为 API 声明 struct 时,请确保它们具有 StructLayout.Sequential 属性。此外,有时您可能需要更改 struct 的打包以使其正常工作,但通常不需要。
  11. 当向 API 方法传递或从 API 方法检索数组时,请查看它是指向数组的指针还是直接输入数组。如果是指针,您可能需要将其封送到 IntPtr
  12. 有时选择要使用的类型可能很困难,但经过几次尝试后您会掌握窍门的。
  13. 当我展示用于指向数据类型指针的类型时,我说是 IntPtr 或它指向的数据类型,有时你可以直接说 ref <datatype>out <datatype>,但除非它是输入 char *,否则对于输入你需要使用 IntPr,对于输出你需要使用 ref IntPtr
  14. 如果您的函数声明未能工作,请不要总是归咎于您编写声明的方式,它可能是之前的方法调用弄乱了它,或者只是传入了错误的数据。
  15. 仅在必要时才使用 MarshalMarshalAs 类,因为在某些情况下它们会占用更多的处理能力。

数据类型转换表:C++ 到 .NET

术语

描述

ATOM

.NET = ushort

C++ = typedef WORD ATOM;

BOOL

.NET = boolint

C++ = typedef int BOOL;

BOOLEAN

.NET = boolbyte

C++ = typedef BYTE BOOLEAN;

BYTE

.NET = byte

C++ = typedef unsigned char BYTE;

CALLBACK

.NET = delegate

C++ = #define CALLBACK __stdcall

CHAR

.NET = char

C++ = typedef char CHAR;

COLORREF

.NET = uint

C++ = typedef DWORD COLORREF;

CONST

.NET = const

C++ = #define CONST const

DWORD

.NET = uint

C++ = typedef unsigned long DWORD;

DWORDLONG

ulong

C++ = typedef ULONGLONG DWORDLONG;

DWORD_PTR

DWORD *

.NET = uintIntPtr

C++ = typedef ULONG_PTR DWORD_PTR;

DWORD32

.NET = uint

C++ = typedef unsigned int DWORD32;

DWORD64

.NET = ulong

C++ = typedef unsigned __int64 DWORD64;

FLOAT

.NET = single

C++ = typedef float FLOAT;

HACCEL

.NET = IntPtr

C++ = typedef HANDLE HACCEL;

HANDLE

.NET = IntPtr

C++ = typedef PVOID HANDLE;

HBITMAP

.NET = IntPtr

C++ = typedef HANDLE HBITMAP;

HBRUSH

.NET = IntPtr

C++ = typedef HANDLE HBRUSH;

HCOLORSPACE

.NET = IntPtr

C++ = if(WINVER >= 0x0400)

C++ = typedef HANDLE HCOLORSPACE;

HCONV

.NET = IntPtr

C++ = typedef HANDLE HCONV;

HCONVLIST

.NET = IntPtr

C++ = typedef HANDLE HCONVLIST;

HCURSOR

.NET = IntPtr

C++ = typedef HICON HCURSOR;

HDC

.NET = IntPtr

C++ = typedef HANDLE HDC;

HDDEDATA

.NET = IntPtr

C++ = typedef HANDLE HDDEDATA;

HDESK

.NET = IntPtr

C++ = typedef HANDLE HDESK;

HDROP

.NET = IntPtr

C++ = typedef HANDLE HDROP;

HDWP

.NET = IntPtr

C++ = typedef HANDLE HDWP;

HENHMETAFILE

.NET = IntPtr

C++ = typedef HANDLE HENHMETAFILE;

HFILE

.NET = int

C++ = typedef int HFILE;

HFONT

.NET = IntPtr

C++ = typedef HANDLE HFONT;

HGDIOBJ

.NET = IntPtr

C++ = typedef HANDLE HGDIOBJ;

HGLOBAL

.NET = IntPtr

C++ = typedef HANDLE HGLOBAL;

HHOOK

.NET = IntPtr

C++ = typedef HANDLE HHOOK;

HICON

.NET = IntPtr

C++ = typedef HANDLE HICON;

HINSTANCE

.NET = IntPtr

C++ = typedef HANDLE HINSTANCE;

HKEY

.NET = IntPtr

C++ = typedef HANDLE HKEY;

HKL

.NET = IntPtr

C++ = typedef HANDLE HKL;

HLOCAL

.NET = IntPtr

C++ = typedef HANDLE HLOCAL;

HMENU

.NET = IntPtr

C++ = typedef HANDLE HMENU;

HMETAFILE

.NET = IntPtr

C++ = typedef HANDLE HMETAFILE;

HMODULE

.NET = IntPtr

C++ = typedef HINSTANCE HMODULE;

HMONITOR

.NET = IntPtr

if(WINVER >= 0x0500)

C++ = typedef HANDLE HMONITOR;

HPALETTE

.NET = IntPtr

C++ = typedef HANDLE HPALETTE;

HPEN

.NET = IntPtr

C++ = typedef HANDLE HPEN;

HRESULT

.NET = intuint

C++ = typedef LONG HRESULT;

HRGN

.NET = IntPtr

C++ = typedef HANDLE HRGN;

HRSRC

.NET = IntPtr

C++ = typedef HANDLE HRSRC;

HSZ

.NET = IntPtr

C++ = typedef HANDLE HSZ;

HWINSTA

.NET = IntPtr

C++ = typedef HANDLE WINSTA;

HWND

.NET = IntPtr

C++ = typedef HANDLE HWND;

INT

.NET = int

C++ = typedef int INT;

INT_PTR

.NET = IntPtr

#if defined(_WIN64)

C++ = typedef __int64 INT_PTR;

#else

C++ = typedef int INT_PTR;

INT32

.NET = int

C++ = typedef signed int INT32;

INT64

.NET = long

C++ = typedef signed __int64 INT64;

LANGID

.NET = ushortint

C++ = typedef WORD LANGID;

LCID

.NET = uint

C++ = typedef DWORD LCID;

LCTYPE

.NET = uint

C++ = typedef DWORD LCTYPE;

LGRPID

.NET = uint

C++ = typedef DWORD LGRPID;

LONG

.NET = int

C++ = typedef long LONG;

LONGLONG

.NET = long

#if !defined(_M_IX86)

C++ = typedef __int64 LONGLONG;

#else

C++ = typedef double LONGLONG;

LONG_PTR

.NET = IntPtr

#if defined(_WIN64)

C++ = typedef __int64 LONG_PTR;

#else

C++ = typedef long LONG_PTR;

LONG32

.NET = int

C++ = typedef signed int LONG32;

LONG64

.NET = long

C++ = typedef __int64 LONG64;

LPARAM

.NET = IntPtr

C++ = typedef LONG_PTR LPARAM;

LPBOOL

Bool *

.NET = IntPtrbool

C++ = typedef BOOL *LPBOOL;

LPBYTE

Byte *

.NET = IntPtrbyte

C++ = typedef BYTE *LPBYTE;

LPCOLORREF

.NET = IntPtruint

C++ = typedef DWORD *LPCOLORREF;

LPCSTR

.NET = stringIntPtrStringBuilder

C++ = typedef CONST CHAR *LPCSTR;

LPCTSTR

.NET = stringIntPtrStringBuilder

#ifdef UNICODE

C++ = typedef LPCWSTR LPCTSTR;

#else

C++ = typedef LPCSTR LPCTSTR;

LPCVOID

.NET = IntPtr

C++ = typedef CONST void *LPCVOID;

LPCWSTR

.NET = stringIntPtrStringBuilder

C++ = typedef CONST WCHAR *LPCWSTR;

LPDWORD

.NET = IntPtruint

C++ = typedef DWORD *LPDWORD;

LPHANDLE

.NET = IntPtr

C++ = typedef HANDLE *LPHANDLE;

LPINT

.NET = IntPtrint

C++ = typedef int *LPINT;

LPLONG

.NET = IntPtrint

C++ = typedef long *LPLONG;

LPSTR

.NET = stringIntPtrStringBuilder

C++ = typedef CHAR *LPSTR;

LPTSTR

.NET = stringIntPtrStringBuilder

#ifdef UNICODE

C++ = typedef LPWSTR LPTSTR;

#else

C++ = typedef LPSTR LPTSTR;

LPVOID

.NET = IntPtr

C++ = typedef void *LPVOID;

LPWORD

.NET = IntPtrushort

C++ = typedef WORD *LPWORD;

LPWSTR

.NET = stringIntPtrStringBuilder

C++ = typedef WCHAR *LPWSTR;

LRESULT

.NET = IntPtrint

C++ = typedef LONG_PTR LRESULT;

PBOOL

.NET = IntPtrbool

C++ = typedef BOOL *PBOOL;

PBOOLEAN

.NET = IntPtrbool

C++ = typedef BOOLEAN *PBOOLEAN;

PBYTE

.NET = IntPtrbyte

C++ = typedef BYTE *PBYTE;

PCHAR

.NET = IntPtrchar

C++ = typedef CHAR *PCHAR;

PCSTR

.NET = stringIntPtrStringBuilder

C++ = typedef CONST CHAR *PCSTR;

PCTSTR

.NET = stringIntPtrStringBuilder

#ifdef UNICODE

C++ = typedef LPCWSTR PCTSTR;

#else

C++ = typedef LPCSTR PCTSTR;

PCWSTR

.NET = stringIntPtrStringBuilder

C++ = typedef CONST WCHAR *PCWSTR;

PDWORD

.NET = IntPtruint

C++ = typedef DWORD *PDWORD;

PDWORDLONG

.NET = IntPtrulong

C++ = typedef DWORDLONG *PDWORDLONG;

PDWORD_PTR

.NET = IntPtruint

C++ = typedef DWORD_PTR *PDWORD_PTR;

PDWORD32

.NET = IntPtruint

C++ = typedef DWORD32 *PDWORD32;

PDWORD64

.NET = IntPtrulong

C++ = typedef DWORD64 *PDWORD64;

PFLOAT

.NET = IntPtrsingle

C++ = typedef FLOAT *PFLOAT;

PHANDLE

.NET = IntPtr

C++ = typedef HANDLE *PHANDLE;

PHKEY

.NET = IntPtr

C++ = typedef HKEY *PHKEY;

PINT

.NET = IntPtrint

C++ = typedef int *PINT;

PINT_PTR

.NET = IntPtr

C++ = typedef INT_PTR *PINT_PTR;

PINT32

.NET = IntPtrint

C++ = typedef INT32 *PINT32;

PINT64

.NET = IntPtrlong

C++ = typedef INT64 *PINT64;

PLCID

.NET = IntPtruint

C++ = typedef PDWORD PLCID;

PLONG

.NET = IntPtrint

C++ = typedef LONG *PLONG;

PLONGLONG

.NET = IntPtrlong

C++ = typedef LONGLONG *PLONGLONG;

PLONG_PTR

.NET = IntPtrint

C++ = typedef LONG_PTR *PLONG_PTR;

PLONG32

.NET = IntPtrint

C++ = typedef LONG32 *PLONG32;

PLONG64

.NET = IntPtrlong

C++ = typedef LONG64 *PLONG64;

POINTER_32

.NET = IntPtrint

#if defined(_WIN64)

#define POINTER_32 __ptr32

#else

#define POINTER32

POINTER_64

.NET = IntPtrlong

#define POINTER_64 __ptr64

PSHORT

.NET = IntPtrshort

C++ = typedef SHORT *PSHORT;

PSIZE_T

.NET = IntPtr

C++ = typedef SIZE_T *PSIZE_T;

PSSIZE_T

.NET = IntPtr

C++ = typedef SSIZE_T *PSSIZE_T;

PSTR

.NET = IntPtrstringStringBuilder

C++ = typedef CHAR *PSTR;

PTBYTE

.NET = IntPtrchar

C++ = typedef TBYTE *PTBYTE;

PTCHAR

.NET = IntPtrstringStringBuilder

C++ = typedef TCHAR *PTCHAR;

PTSTR

.NET = IntPtrstringStringBuilder

#ifdef UNICODE

C++ = typedef LPWSTR PTSTR;

#else

C++ = typedef LPSTR PTSTR;

PUCHAR

.NET = IntPtrstringStringBuilder

C++ = typedef UCHAR *PUCHAR;

PUINT

.NET = IntPtruint

C++ = typedef UINT *PUINT;

PUINT_PTR

.NET = IntPtruint

C++ = typedef UINT_PTR *PUINT_PTR;

PUINT32

.NET = IntPtruint

C++ = typedef UINT32 *PUINT32;

PUINT64

.NET = IntPtrulong

C++ = typedef UINT64 *PUINT64;

PULONG

.NET = IntPtruint

C++ = typedef ULONG *PULONG;

PULONGLONG

.NET = IntPtrulong

C++ = typedef ULONGLONG *PULONGLONG;

PULONG_PTR

.NET = IntPtruint

C++ = typedef ULONG_PTR *PULONG_PTR;

PULONG32

.NET = IntPtruint

C++ = typedef ULONG32 *PULONG32;

PULONG64

.NET = IntPtrulong

C++ = typedef ULONG64 *PULONG64;

PUSHORT

.NET = IntPtrushort

C++ = typedef USHORT *PUSHORT;

PVOID

.NET = IntPtr

C++ = typedef void *PVOID;

PWCHAR

.NET = IntPtrstring

C++ = typedef WCHAR *PWCHAR;

PWORD

.NET = IntPtrushort

C++ = typedef WORD *PWORD;

PWSTR

.NET = IntPtrstringStringBuilder

C++ = typedef WCHAR *PWSTR;

SC_HANDLE

.NET = IntPtr

C++ = typedef HANDLE SC_HANDLE;

SC_LOCK

.NET = IntPtr

C++ = typedef LPVOID SC_LOCK;

SERVICE_STATUS_HANDLE

.NET = IntPtr

C++ = typedef HANDLE SERVICE_STATUS_HANDLE;

SHORT

.NET = short

C++ = typedef short SHORT;

SIZE_T

.NET = uintIntPtr

C++ = typedef ULONG_PTR SIZE_T;

SSIZE_T

.NET = intIntPtr

C++ = typedef LONG_PTR SSIZE_T;

TBYTE

.NET = char

#ifdef UNICODE

C++ = typedef WCHAR TBYTE;

#else

C++ = typedef unsigned char TBYTE;

TCHAR

.NET = char

#ifdef UNICODE

C++ = typedef WCHAR TCHAR;

#else

C++ = typedef char TCHAR;

UCHAR

.NET = char

C++ = typedef unsigned char UCHAR;

UINT

.NET = uint

C++ = typedef unsigned int UINT;

UINT_PTR

.NET = UIntPtruint

#if defined(_WIN64)

C++ = typedef unsigned __int64 UINT_PTR;

#else

C++ = typedef unsigned int UINT_PTR;

UINT32

.NET = uint

C++ = typedef unsigned int

UINT32;

UINT64

.NET = ulong

C++ = typedef usigned __int

64 UINT64;

ULONG

.NET = uint

C++ = typedef unsigned long ULONG;

ULONGLONG

.NET = ulong

#if !defined(_M_IX86)

C++ = typedef unsigned __int64 ULONGLONG;

#else

C++ = typedef double ULONGLONG

ULONG_PTR

.NET = IntPtruint

#if defined(_WIN64)

C++ = typedef unsigned __int64 ULONG_PTR;

#else

C++ = typedef unsigned long ULONG_PTR;

ULONG32

.NET = uint

C++ = typedef unsigned int ULONG32;

ULONG64

.NET = ulong

C++ = typedef unsigned __int64 ULONG64;

USHORT

.NET = ushort

C++ = typedef unsigned short USHORT;

USN

.NET = long

C++ = typedef LONGLONG USN;

VOID

.NET = void

#define VOID void

WCHAR

.NET = char

C++ = typedef wchar_t WCHAR;

WINAPI

.NET = default 为标准,请查看 CallingConvention 枚举

#define WINAPI __stdcall

WORD

.NET = ushort

C++ = typedef unsigned short WORD;

WPARAM

.NET = IntPtruint

C++ = typedef UINT_PTR WPARAM;

© . All rights reserved.