现在就把“C# 调用Dll中非托管C++代码时,函数参数的类型对照”这一问题做一个总结。
用这些关键字进行搜索,网上有不少这样那个的内容,比如下面这几个链接
C# 与 C++ 数据类型对照(后三篇内容一样)
http://topic.csdn.net/u/20090928/11/af7848c6-5071-41aa-92e2-e8d626d6aefe.html
http://blog.csdn.net/dz45693/archive/2009/09/26/4598867.aspx
http://www.cnblogs.com/yiki/archive/2008/10/29/1321848.html
http://blog.csdn.net/okadler0518/archive/2009/06/22/4289679.aspx
但是上面的映射有时候会出现问题。
比如上面的帖子都将LPTSTR映射成String,
然而在处理GetWindowText 函数是,因为这个LPTSTR是为了要将结果带回来的返回值。
因此在这里使用String便行不通了,而需要使用StringBuffer。
注:GetWindowText的原型
- int GetWindowText(
- HWND hWnd,
- LPTSTR lpString,
- int nMaxCount
- );
如果问题的方法,仅仅是查看上面那几个链接,那么我一定不会写这篇博客。
我的主要目的是要介绍另外两种方法。
方法一:
查看Web版本的MSDN。
看看下面这两个连接,在Community Content部分都给出了C#,VB调用的原型。
当然,不是所有的函数对应的Community Content部分都有完整的事例。
但有的给出了一些常量的值,有的给出了一些结构体的定义,总之这部分内容还是具有参考价值。
注:安装在本机的MSDN没有Community Content这部分内容。
GetWindowText
http://msdn.microsoft.com/en-us/library/ms633520%28VS.85%29.aspx
GetForegroundWindow
http://msdn.microsoft.com/en-us/library/ms633505%28VS.85%29.aspx
方法二:
输入你想要的东西(Type,Constant,Procedure),他会自动生成相应的代码(C#,或VB)。
举例子说明。
当我要SHGetFileInfo调用这个函数是,需要用到类型:SHFileInfo
于是我在P/Invoke Interop Assistant查询类型SHFileInfo,便会得到下面结果:
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Unicode)]
- public struct SHFILEINFOW {
- /// HICON->HICON__*
- public System.IntPtr hIcon;
- /// int
- public int iIcon;
- /// DWORD->unsigned int
- public uint dwAttributes;
- /// WCHAR[260]
- [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=260)]
- public string szDisplayName;
- /// WCHAR[80]
- [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=80)]
- public string szTypeName;
- }
再举一个例子。
对于前面提到的GetWindowText函数,如果在P/Invoke Interop Assistant的Procedure中进行查询的话。
也会得到下面的代码:
- [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowText")]
- public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
上面这段代码有经过我整理,自动生成的东西,可读性还是烧差一些,有冗余的东西。
尽管如此这一工具还是非常好用。
总结起来
配合这个工具,还有本文开头部分提到的C# 与 C++ 数据类型对照表。
分析分析,查找查找,是在不行再GoogleGoogle。
在C#中调用非托管dll代码,还是很方便的。
方便起见,我也将《C# 与 C++ 数据类型对照表》转载如下:
C++ C#
=====================================
WORD ushort
DWORD uint
UCHAR int/byte 大部分情况都可以使用int代替,而如果需要严格对齐的话则应该用bytebyte
UCHAR* string/IntPtr
unsigned char* [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)
char* string
LPCTSTR string
LPTSTR [MarshalAs(UnmanagedType.LPTStr)] string
long int
ulong uint
Handle IntPtr
HWND IntPtr
void* IntPtr
int int
int* ref int
*int IntPtr
unsigned int uint
COLORREF uint
API与C#的数据类型对应关系表 | |||||
API数据类型 | 类型描述 | C#类型 | API数据类型 | 类型描述 | C#类型 |
WORD | 16位无符号整数 | ushort | CHAR | 字符 | char |
LONG | 32位无符号整数 | int | DWORDLONG | 64位长整数 | long |
DWORD | 32位无符号整数 | uint | HDC | 设备描述表句柄 | int |
HANDLE | 句柄,32位整数 | int | HGDIOBJ | GDI对象句柄 | int |
UINT | 32位无符号整数 | uint | HINSTANCE | 实例句柄 | int |
BOOL | 32位布尔型整数 | bool | HWM | 窗口句柄 | int |
LPSTR | 指向字符的32位指针 | string | HPARAM | 32位消息参数 | int |
LPCSTR | 指向常字符的32位指针 | String | LPARAM | 32位消息参数 | int |
BYTE | 字节 | byte | WPARAM | 32位消息参数 | int |
BOOL=System.Int32
BOOLEAN=System.Int32
BYTE=System.UInt16
CHAR=System.Int16
COLORREF=System.UInt32
DWORD=System.UInt32
DWORD32=System.UInt32
DWORD64=System.UInt64
FLOAT=System.Float
HACCEL=System.IntPtr
HANDLE=System.IntPtr
HBITMAP=System.IntPtr
HBRUSH=System.IntPtr
HCONV=System.IntPtr
HCONVLIST=System.IntPtr
HCURSOR=System.IntPtr
HDC=System.IntPtr
HDDEDATA=System.IntPtr
HDESK=System.IntPtr
HDROP=System.IntPtr
HDWP=System.IntPtr
HENHMETAFILE=System.IntPtr
HFILE=System.IntPtr
HFONT=System.IntPtr
HGDIOBJ=System.IntPtr
HGLOBAL=System.IntPtr
HHOOK=System.IntPtr
HICON=System.IntPtr
HIMAGELIST=System.IntPtr
HIMC=System.IntPtr
HINSTANCE=System.IntPtr
HKEY=System.IntPtr
HLOCAL=System.IntPtr
HMENU=System.IntPtr
HMETAFILE=System.IntPtr
HMODULE=System.IntPtr
HMONITOR=System.IntPtr
HPALETTE=System.IntPtr
HPEN=System.IntPtr
HRGN=System.IntPtr
HRSRC=System.IntPtr
HSZ=System.IntPtr
HWINSTA=System.IntPtr
HWND=System.IntPtr
INT=System.Int32
INT32=System.Int32
INT64=System.Int64
LONG=System.Int32
LONG32=System.Int32
LONG64=System.Int64
LONGLONG=System.Int64
LPARAM=System.IntPtr
LPBOOL=System.Int16[]
LPBYTE=System.UInt16[]
LPCOLORREF=System.UInt32[]
LPCSTR=System.String
LPCTSTR=System.String
LPCVOID=System.UInt32
LPCWSTR=System.String
LPDWORD=System.UInt32[]
LPHANDLE=System.UInt32
LPINT=System.Int32[]
LPLONG=System.Int32[]
LPSTR=System.String
LPTSTR=System.String
LPVOID=System.UInt32
LPWORD=System.Int32[]
LPWSTR=System.String
LRESULT=System.IntPtr
PBOOL=System.Int16[]
PBOOLEAN=System.Int16[]
PBYTE=System.UInt16[]
PCHAR=System.Char[]
PCSTR=System.String
PCTSTR=System.String
PCWCH=System.UInt32
PCWSTR=System.UInt32
PDWORD=System.Int32[]
PFLOAT=System.Float[]
PHANDLE=System.UInt32
PHKEY=System.UInt32
PINT=System.Int32[]
PLCID=System.UInt32
PLONG=System.Int32[]
PLUID=System.UInt32
PSHORT=System.Int16[]
PSTR=System.String
PTBYTE=System.Char[]
PTCHAR=System.Char[]
PTSTR=System.String
PUCHAR=System.Char[]
PUINT=System.UInt32[]
PULONG=System.UInt32[]
PUSHORT=System.UInt16[]
PVOID=System.UInt32
PWCHAR=System.Char[]
PWORD=System.Int16[]
PWSTR=System.String
REGSAM=System.UInt32
SC_HANDLE=System.IntPtr
SC_LOCK=System.IntPtr
SHORT=System.Int16
SIZE_T=System.UInt32
SSIZE_=System.UInt32
TBYTE=System.Char
TCHAR=System.Char
UCHAR=System.Byte
UINT=System.UInt32
UINT32=System.UInt32
UINT64=System.UInt64
ULONG=System.UInt32
ULONG32=System.UInt32
ULONG64=System.UInt64
ULONGLONG=System.UInt64
USHORT=System.UInt16
WORD=System.UInt16
WPARAM=System.IntPtr
<---------补充----------->
Wtypes.h 中的非托管类型 非托管C 语言类型 托管类名 说明
HANDLE void* System.IntPtr 32 位
BYTE unsigned char System.Byte 8 位
SHORT short System.Int16 16 位
WORD unsigned short System.UInt16 16 位
INT int System.Int32 32 位
UINT unsigned int System.UInt32 32 位
LONG long System.Int32 32 位
BOOL long System.Int32 32 位
DWORD unsigned long System.UInt32 32 位
ULONG unsigned long System.UInt32 32 位
CHAR char System.Char 用 ANSI 修饰。
LPSTR char* System.String 或 System.StringBuilder 用 ANSI 修饰。
LPCSTR Const char* System.String 或 System.StringBuilder 用 ANSI 修饰。
LPWSTR wchar_t* System.String 或 System.StringBuilder 用 Unicode 修饰。
LPCWSTR Const wchar_t* System.String 或 System.StringBuilder 用 Unicode 修饰。
FLOAT Float System.Single 32 位
DOUBLE Double System.Double 64 位