本以為這篇搜集整理的代碼會是很不錯的文章,花了一天時間,搜尋到最後居然出來一篇叫做"C# 與 C++ 資料類型對照表"的文章.幾乎囊括掉和大部分的資料了,太打擊我了. 本文中有部分的資料沒有測試.也有一些不錯的是看了上百篇網文對比整理得來的.希望有協助.
/C++中的DLL函數原型為 //extern "C" __declspec(dllexport) bool 方法名一(const char* 變數名1, unsigned char* 變數名2) //extern "C" __declspec(dllexport) bool 方法名二(const unsigned char* 變數名1, char* 變數名2) //C#調用C++的DLL搜集整理的所有資料類型轉換方式,可能會有重複或者多種方案,自己多測試 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byte(unsigned char) ---- c#:System.Byte //c++:SHORT(short) ---- c#:System.Int16 //c++:WORD(unsigned short) ---- c#:System.UInt16 //c++:INT(int) ---- c#:System.Int16 //c++:INT(int) ---- c#:System.Int32 //c++:UINT(unsigned int) ---- c#:System.UInt16 //c++:UINT(unsigned int) ---- c#:System.UInt32 //c++:LONG(long) ---- c#:System.Int32 //c++:ULONG(unsigned long) ---- c#:System.UInt32 //c++:DWORD(unsigned long) ---- c#:System.UInt32 //c++:DECIMAL ---- c#:System.Decimal //c++:BOOL(long) ---- c#:System.Boolean //c++:CHAR(char) ---- c#:System.Char //c++:LPSTR(char *) ---- c#:System.String //c++:LPWSTR(wchar_t *) ---- c#:System.String //c++:LPCSTR(const char *) ---- c#:System.String //c++:LPCWSTR(const wchar_t *) ---- c#:System.String //c++:PCAHR(char *) ---- c#:System.String //c++:BSTR ---- c#:System.String //c++:FLOAT(float) ---- c#:System.Single //c++:DOUBLE(double) ---- c#:System.Double //c++:VARIANT ---- c#:System.Object //c++:PBYTE(byte *) ---- c#:System.Byte[] //c++:BSTR ---- c#:StringBuilder //c++:LPCTSTR ---- c#:StringBuilder //c++:LPCTSTR ---- c#:string //c++:LPTSTR ---- c#:[MarshalAs(UnmanagedType.LPTStr)] string //c++:LPTSTR 輸出變數名 ---- c#:StringBuilder 輸出變數名 //c++:LPCWSTR ---- c#:IntPtr //c++:BOOL ---- c#:bool //c++:HMODULE ---- c#:IntPtr //c++:HINSTANCE ---- c#:IntPtr //c++:結構體 ---- c#:public struct 結構體{}; //c++:結構體 **變數名 ---- c#:out 變數名 //C#中提前申明一個結構體執行個體化後的變數名 //c++:結構體 &變數名 ---- c#:ref 結構體 變數名 //c++:WORD ---- c#:ushort //c++:DWORD ---- c#:uint //c++:DWORD ---- c#:int //c++:UCHAR ---- c#:int //c++:UCHAR ---- c#:byte //c++:UCHAR* ---- c#:string //c++:UCHAR* ---- c#:IntPtr //c++:GUID ---- c#:Guid //c++:Handle ---- c#:IntPtr //c++:HWND ---- c#:IntPtr //c++:DWORD ---- c#:int //c++:COLORREF ---- c#:uint //c++:unsigned char ---- c#:byte //c++:unsigned char * ---- c#:ref byte //c++:unsigned char * ---- c#:[MarshalAs(UnmanagedType.LPArray)] byte[] //c++:unsigned char * ---- c#:[MarshalAs(UnmanagedType.LPArray)] Intptr //c++:unsigned char & ---- c#:ref byte //c++:unsigned char 變數名 ---- c#:byte 變數名 //c++:unsigned short 變數名 ---- c#:ushort 變數名 //c++:unsigned int 變數名 ---- c#:uint 變數名 //c++:unsigned long 變數名 ---- c#:ulong 變數名 //c++:char 變數名 ---- c#:byte 變數名 //C++中一個字元用一個位元組表示,C#中一個字元用兩個位元組表示 //c++:char 數組名[數組大小] ---- c#:MarshalAs(UnmanagedType.ByValTStr, SizeConst = 數組大小)] public string 數組名; ushort //c++:char * ---- c#:string //傳入參數 //c++:char * ---- c#:StringBuilder//傳出參數 //c++:char *變數名 ---- c#:ref string 變數名 //c++:char *輸入變數名 ---- c#:string 輸入變數名 //c++:char *輸出變數名 ---- c#:[MarshalAs(UnmanagedType.LPStr)] StringBuilder 輸出變數名 //c++:char ** ---- c#:string //c++:char **變數名 ---- c#:ref string 變數名 //c++:const char * ---- c#:string //c++:char[] ---- c#:string //c++:char 變數名[數組大小] ---- c#:[MarshalAs(UnmanagedType.ByValTStr,SizeConst=數組大小)] public string 變數名; //c++:struct 結構體名 *變數名 ---- c#:ref 結構體名 變數名 //c++:委託 變數名 ---- c#:委託 變數名 //c++:int ---- c#:int //c++:int ---- c#:ref int //c++:int & ---- c#:ref int //c++:int * ---- c#:ref int //C#中調用前需定義int 變數名 = 0; //c++:*int ---- c#:IntPtr //c++:int32 PIPTR * ---- c#:int32[] //c++:float PIPTR * ---- c#:float[] //c++:double** 數組名 ---- c#:ref double 數組名 //c++:double*[] 數組名 ---- c#:ref double 數組名 //c++:long ---- c#:int //c++:ulong ---- c#:int //c++:UINT8 * ---- c#:ref byte //C#中調用前需定義byte 變數名 = new byte(); //c++:handle ---- c#:IntPtr //c++:hwnd ---- c#:IntPtr //c++:void * ---- c#:IntPtr //c++:void * user_obj_param ---- c#:IntPtr user_obj_param //c++:void * 對象名稱 ---- c#:([MarshalAs(UnmanagedType.AsAny)]Object 對象名稱 //c++:char, INT8, SBYTE, CHAR ---- c#:System.SByte //c++:short, short int, INT16, SHORT ---- c#:System.Int16 //c++:int, long, long int, INT32, LONG32, BOOL , INT ---- c#:System.Int32 //c++:__int64, INT64, LONGLONG ---- c#:System.Int64 //c++:unsigned char, UINT8, UCHAR , BYTE ---- c#:System.Byte //c++:unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t ---- c#:System.UInt16 //c++:unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT ---- c#:System.UInt32 //c++:unsigned __int64, UINT64, DWORDLONG, ULONGLONG ---- c#:System.UInt64 //c++:float, FLOAT ---- c#:System.Single //c++:double, long double, DOUBLE ---- c#:System.Double //Win32 Types ---- CLR Type //Struct需要在C#裡重新定義一個Struct //CallBack回呼函數需要封裝在一個委託裡,delegate static extern int FunCallBack(string str); //unsigned char** ppImage替換成IntPtr ppImage //int& nWidth替換成ref int nWidth //int*, int&, 則都可用 ref int 對應 //雙針指型別參數,可以用 ref IntPtr //函數指標使用c++: typedef double (*fun_type1)(double); 對應 c#:public delegate double fun_type1(double); //char* 的操作c++: char*; 對應 c#:StringBuilder; //c#中使用指標:在需要使用指標的地方 加 unsafe //unsigned char對應public byte /* * typedef void (*CALLBACKFUN1W)(wchar_t*, void* pArg); * typedef void (*CALLBACKFUN1A)(char*, void* pArg); * bool BIOPRINT_SENSOR_API dllFun1(CALLBACKFUN1 pCallbackFun1, void* pArg); * 調用方式為 * [UnmanagedFunctionPointer(CallingConvention.Cdecl)] * public delegate void CallbackFunc1([MarshalAs(UnmanagedType.LPWStr)] StringBuilder strName, IntPtr pArg); * * */
C++ C#=====================================WORD ushortDWORD uintUCHAR int/byte 大部分情況都可以使用int代替,而如果需要嚴格對齊的話則應該用bytebyteUCHAR* string/IntPtrunsigned char* [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)char* stringLPCTSTR stringLPTSTR [MarshalAs(UnmanagedType.LPTStr)] stringlong intulong uintHandle IntPtrHWND IntPtrvoid* IntPtrint intint* ref int*int IntPtrunsigned int uintCOLORREF uintAPI與C#的資料類型對應關係表API資料類型 類型描述 C#類型 API資料類型 類型描述 C#類型WORD 16位不帶正負號的整數 ushort CHAR 字元 charLONG 32位不帶正負號的整數 int DWORDLONG 64位長整數 longDWORD 32位不帶正負號的整數 uint HDC 裝置描述表控制代碼 intHANDLE 控制代碼,32位整數 int HGDIOBJ GDI 物件控點 intUINT 32位不帶正負號的整數 uint HINSTANCE 執行個體控制代碼 intBOOL 32位布爾型整數 bool HWM 視窗控制代碼 intLPSTR 指向字元的32位指標 string HPARAM 32位訊息參數 intLPCSTR 指向常字元的32位指標 String LPARAM 32位訊息參數 intBYTE 位元組 byte WPARAM 32位訊息參數 intBOOL=System.Int32BOOLEAN=System.Int32BYTE=System.UInt16CHAR=System.Int16COLORREF=System.UInt32DWORD=System.UInt32DWORD32=System.UInt32DWORD64=System.UInt64FLOAT=System.FloatHACCEL=System.IntPtrHANDLE=System.IntPtrHBITMAP=System.IntPtrHBRUSH=System.IntPtrHCONV=System.IntPtrHCONVLIST=System.IntPtrHCURSOR=System.IntPtrHDC=System.IntPtrHDDEDATA=System.IntPtrHDESK=System.IntPtrHDROP=System.IntPtrHDWP=System.IntPtrHENHMETAFILE=System.IntPtrHFILE=System.IntPtrHFONT=System.IntPtrHGDIOBJ=System.IntPtrHGLOBAL=System.IntPtrHHOOK=System.IntPtrHICON=System.IntPtrHIMAGELIST=System.IntPtrHIMC=System.IntPtrHINSTANCE=System.IntPtrHKEY=System.IntPtrHLOCAL=System.IntPtrHMENU=System.IntPtrHMETAFILE=System.IntPtrHMODULE=System.IntPtrHMONITOR=System.IntPtrHPALETTE=System.IntPtrHPEN=System.IntPtrHRGN=System.IntPtrHRSRC=System.IntPtrHSZ=System.IntPtrHWINSTA=System.IntPtrHWND=System.IntPtrINT=System.Int32INT32=System.Int32INT64=System.Int64LONG=System.Int32LONG32=System.Int32LONG64=System.Int64LONGLONG=System.Int64LPARAM=System.IntPtrLPBOOL=System.Int16[]LPBYTE=System.UInt16[]LPCOLORREF=System.UInt32[]LPCSTR=System.StringLPCTSTR=System.StringLPCVOID=System.UInt32LPCWSTR=System.StringLPDWORD=System.UInt32[]LPHANDLE=System.UInt32LPINT=System.Int32[]LPLONG=System.Int32[]LPSTR=System.StringLPTSTR=System.StringLPVOID=System.UInt32LPWORD=System.Int32[]LPWSTR=System.StringLRESULT=System.IntPtrPBOOL=System.Int16[]PBOOLEAN=System.Int16[]PBYTE=System.UInt16[]PCHAR=System.Char[]PCSTR=System.StringPCTSTR=System.StringPCWCH=System.UInt32PCWSTR=System.UInt32PDWORD=System.Int32[]PFLOAT=System.Float[]PHANDLE=System.UInt32PHKEY=System.UInt32PINT=System.Int32[]PLCID=System.UInt32PLONG=System.Int32[]PLUID=System.UInt32PSHORT=System.Int16[]PSTR=System.StringPTBYTE=System.Char[]PTCHAR=System.Char[]PTSTR=System.StringPUCHAR=System.Char[]PUINT=System.UInt32[]PULONG=System.UInt32[]PUSHORT=System.UInt16[]PVOID=System.UInt32PWCHAR=System.Char[]PWORD=System.Int16[]PWSTR=System.StringREGSAM=System.UInt32SC_HANDLE=System.IntPtrSC_LOCK=System.IntPtrSHORT=System.Int16SIZE_T=System.UInt32SSIZE_=System.UInt32TBYTE=System.CharTCHAR=System.CharUCHAR=System.ByteUINT=System.UInt32UINT32=System.UInt32UINT64=System.UInt64ULONG=System.UInt32ULONG32=System.UInt32ULONG64=System.UInt64ULONGLONG=System.UInt64USHORT=System.UInt16WORD=System.UInt16WPARAM=System.IntPtrWtypes.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; }其它代碼不用作修改便可使用。