C# 调用Dll中非托管C++代码,函数参数的类型对照

来源:互联网 发布:c语言开发工具下载 编辑:程序博客网 时间:2024/05/16 19:26
 

对于一维数组,C#参数在基本类型前加ref或out,out表示有返回数据。

如调用 c++的f(float[] a), 在c#中,为f(ref a).

对数据结构,

c++

struct SAMPLE_DATA{

byte SampleID[255];

float Value[6];   

}

C#

[StructLayout(LayoutKind.Sequential)]
unsafe public struct SAMPLE_DATA
{
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
            public byte[] SampleID;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public float[] Value;   

}

以下是基本数据类型的对照。

[转自]http://wjason.javaeye.com/blog/491410

使用#调用了很多非托管的++代码。

现在就把“# 调用中非托管++代码时,函数参数的类型对照”这一问题做一个总结。

用这些关键字进行搜索,网上有不少这样那个的内容,比如下面这几个链接

# 与 ++ 数据类型对照(后三篇内容一样)

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,

然而在处理 函数是,因为这个LPTSTR是为了要将结果带回来的返回值。

因此在这里使用String便行不通了,而需要使用StringBuffer。

注:GetWindowText的原型

Cpp代码 复制代码
  1. GetWindowText(         
  2.      hWnd,   
  3.      lpString,   
  4.      nMaxCount   
  5. );  
int GetWindowText(          HWND hWnd,    LPTSTR lpString,    int nMaxCount);

如果问题的方法,仅仅是查看上面那几个链接,那么我一定不会写这篇博客。

我的主要目的是要介绍另外两种方法。

方法一:

查看Web版本的MSDN。

看看下面这两个连接,在Community Content部分都给出了#,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),他会自动生成相应的代码(#,或VB)。

举例子说明。

当我要SHGetFileInfo调用这个函数是,需要用到类型:SHFileInfo

于是我在P/Invoke Interop Assistant查询类型SHFileInfo,便会得到下面结果:

#代码 复制代码
  1. [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Unicode)]   
  2. SHFILEINFOW {   
  3.        
  4.       
  5.      System.IntPtr hIcon;   
  6.        
  7.       
  8.      iIcon;   
  9.        
  10.       
  11.      dwAttributes;   
  12.        
  13.       
  14.      [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=260)]   
  15.      szDisplayName;   
  16.        
  17.       
  18.      [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=80)]   
  19.      szTypeName;   
  20. }  
[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中进行查询的话。

也会得到下面的代码:

#代码 复制代码
  1. [System.Runtime.InteropServices.DllImportAttribute(, EntryPoint =)]   
  2. GetWindowText(IntPtr hWnd, StringBuilder lpString,nMaxCount);  
[System.Runtime.InteropServices.DllImportAttribute("user32.", EntryPoint = "GetWindowText")]public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

上面这段代码有经过我整理,自动生成的东西,可读性还是烧差一些,有冗余的东西。

尽管如此这一工具还是非常好用。

总结起来

配合这个工具,还有本文开头部分提到的# 与 ++ 数据类型对照表。

分析分析,查找查找,是在不行再GoogleGoogle。

#中调用非托管代码,还是很方便的。

方便起见,我也将《# 与 ++ 数据类型对照表》转载如下:

++            #
=====================================
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与#的数据类型对应关系表
API数据类型类型描述#类型API数据类型类型描述#类型WORD16位无符号整数ushortCHAR字符charLONG32位无符号整数intDWORDLONG64位长整数longDWORD32位无符号整数uintHDC设备描述表句柄intHANDLE句柄,32位整数intHGDIOBJGDI对象句柄intUINT32位无符号整数uintHINSTANCE实例句柄intBOOL32位布尔型整数boolHWM窗口句柄intLPSTR指向字符的32位指针stringHPARAM32位消息参数intLPCSTR指向常字符的32位指针StringLPARAM32位消息参数intBYTE字节byteWPARAM32位消息参数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 中的非托管类型    非托管 语言类型    托管类名       说明
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 位

原创粉丝点击