读书人

C# 与 C++ 数据类型比较及构造体转换

发布时间: 2012-08-30 09:55:54 作者: rapoo

C# 与 C++ 数据类型比较及结构体转换
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#类型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 中的非托管类型??? 非托管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 位

?

?

C/C++中的结构类型数据在C#下的转换

?在做项目移植的时候,经常会碰到数据类型的转换,而我这一次碰到的是C/C++中的结构怎样转换到C#。折腾了一个晚上终于有一个完美的方案。
例如我们在C/C++下的结构数据如下:
typedef struct
{
??? char sLibName[ 256 ];
??? char sPathToLibrary[ 256 ];
??? INT32??? ??? iEntries;
??? INT32??? ??? iUsed;
??? UINT16??? iSort;
??? UINT16??? iVersion;
??? BOOLEAN??? fContainsSubDirectories;
??? INT32??? ??? iReserved;
} LIBHEADER;
我们想把它转成C#下的结构类型如下:
??? public struct LIBHEADER
??? {
??? ??? public char[] sLibName;
??? ??? public char[] sPathToLibrary;
??? ??? public Int32 iEntries;
??? ??? public Int32 iUsed;
??? ??? public UInt16 iSort;
??? ??? public UInt16 iVersion;
??? ??? public Boolean fContainsSubDirectories;
??? ??? public Int32 iReserved;
??? }
看上去好像没问题了,呵呵呵,其实这样是不行的,我们得再给C#编译器一些信息,告诉它一些字符数组的大小。然后它们在C#下面长得样子就变成这样:
??? [StructLayout(LayoutKind.Sequential)]
??? public struct LIBHEADER
??? {
??? ??? [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
??? ??? public char[] sLibName;
??? ??? [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
??? ??? public char[] sPathToLibrary;
??? ??? public Int32 iEntries;
??? ??? public Int32 iUsed;
??? ??? public UInt16 iSort;
??? ??? public UInt16 iVersion;
??? ??? public Boolean fContainsSubDirectories;
??? ??? public Int32 iReserved;
??? }
然后写一个函数负责转换。
public StructType ConverBytesToStructure<StructType>(byte[] bytesBuffer)
??? ??? {
??? ??? ??? // 检查长度。
??? ??? ??? if (bytesBuffer.Length != Marshal.SizeOf(typeof(StructType)))
??? ??? ??? {
??? ??? ??? ??? throw new ArgumentException("bytesBuffer参数和structObject参数字节长度不一致。");
??? ??? ??? }

??? ??? ??? IntPtr bufferHandler = Marshal.AllocHGlobal(bytesBuffer.Length);
??? ??? ??? for (int index = 0; index < bytesBuffer.Length; index++)
??? ??? ??? {
??? ??? ??? ??? Marshal.WriteByte(bufferHandler, index, bytesBuffer[index]);
??? ??? ??? }
??? ??? ??? StructType structObject = (StructType)Marshal.PtrToStructure(bufferHandler, typeof(StructType));
??? ??? ??? Marshal.FreeHGlobal(bufferHandler);
??? ??? ??? return structObject;
??? ??? }
然后我们的函数用例是这样:
??? FileStream file = File.OpenRead(@"D:\Jagged Alliance 2 Gold\INSTALL.LOG");
??? byte[] buffer = new byte[Marshal.SizeOf(typeof(LIBHEADER))];
??? file.Read(buffer, 0, buffer.Length);
??? LIBHEADER testValue = CommonTools.ConverBytesToStructure<LIBHEADER>(buffer);
string libName = new string(testValue.sLibName);
string pathToLibrary= new string(testValue.sPathToLibrary);
OK,搞定。
如果想去掉后面两句的char数组的转换哪代码如下
C#中的结构代码
??? [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
??? public struct LIBHEADER
??? {
??? ??? [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
??? ??? public string sLibName;
??? ??? [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
??? ??? public string sPathToLibrary;
??? ??? public Int32 iEntries;
??? ??? public Int32 iUsed;
??? ??? public UInt16 iSort;
??? ??? public UInt16 iVersion;
??? ??? public Boolean fContainsSubDirectories;
??? ??? public Int32 iReserved;
??? }
其它代码不用作修改便可使用。

读书人网 >C++

热点推荐