1. C#類型與C/C++類型的對應關系
基本資料類型(C# <—> C/C++)
- System.Int32,int <—> int, long
- System.Int64,int64 <—> long long, __int64
- System.Char, char <—> char, byte, unsigned char
- System.Int16, short <—> short
- System.UInt32, uint <—> unsigned int, unsigned long
- System.UInt16, ushort <—> unsigned short, DWORD
- System.String, string <—> char[], char *, const char *
- System.IntPtr <—> void *, [Type]*
- Sytem.Boolean, bool <—> bool, BOOL
2. C/C++函數參數類型與C#類型對應關系
① 基本的資料類型對應關系與1相同,但是也有一些不一樣的地方
② const char * 一般作為輸入參數, C#直接使用string類型即可(StringBuilder也可以)
③ char *作為輸入參數的時候, C#需要使用ref string類型或者StringBuilder類型
④ 結構體指針做輸入參數的時候, C#一般使用ref + 對應的結構體類型
3. C/C++結構體與C#結構體的成員類型對應關系
A. 如果C/C++結構體成員類型是基本資料類型, C#中對應的結構體成員類型使用1中的對應關系即可, 如:
C/C++代碼
struct Some
{
int number;
char character;
char name[32];
}
C#代碼
struct Some
{
int number;
char charactor;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
string name;
}
B. 如果C/C++的結構體成員中包含的成員仍然是結構體(單個,非數組), 則對應的C#結構體隻需要同樣包含結構體, 如:
C/C++代碼
struct A
{
int number;
};
struct B
{
struct A a;
int otherNumber;
};
對應的C#代碼
public struct A
{
public int number;
}
public struct B
{
public A a;
public int otherNumber;
}
###C. 如果C/C++結構體成員中包含數組(長度固定),則C#結構體中也使用數組對應的類型, 如:
C/C++代碼
struct A
{
int number;
};
struct B
{
int numbers[10];
struct A alist[5];
};
對應的C#代碼
public struct A
{
int number;
}
public struct B
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=10, ArraySubType=UnmanagedType.SysInt)]
public int[] numbers;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=10, ArraySubType=UnmanagedType.Struct)]
public A[] alist;
}
###D. 如果C/C++的結構體成員中包含另一個結構體的指針,C#對應的結構體中一律使用IntPtr類型, 如:
C/C++代碼
struct A
{
int number;
};
struct B
{
int tag;
struct A *pA;
}
對應的C#代碼
public struct A
{
public int number;
}
public struct B
{
public int tag;
public IntPtr pA;
}
然後在使用的時候需要用到Marshal類的StructureToPtr和PtrToStructure方法進行轉換
轉換方法如下:
(1)結構體轉換成IntPtr
A a = new A();
B b = new B();
IntPtr pA= Marshal.AllocHGlobal(Marshal.SizeOf(a));
Marshal.StructureToPtr(a, pA, false);
b.pA = pA;
(2)IntPtr 轉換成結構體
B b = new B();
//...省略中間的操作過程
A aInB = (A)Marshal.PtrToStructure(b.pA, typeof(A))
//或者
A aInB = new A();
Marshal.PtrToStructure(b.pA, aInB);
4. 關于類型轉換中的數組長度
- C/C++中,如果是char類型的數組(一般表示最大長度不超過某個數字的字元串),那麼在進行參數傳遞的時候,如果C#中的string字元串位元組數超過了C/C++中的最大位元組數,則會發生截斷, 如C/C++中, char name[3]; 但是在C#中卻使用了string name = “Jack”,實際傳到C/C++中, name中的内容為“Ja”,多餘的部分沒有填充進來
- C/C++中使用的數組為定長數組,在參數傳遞過程中,如果C#中使用的數組長度比C/C++中數組長度短,則會發生System.ArgumentException異常,提示“未能封送類型,因為嵌入數組執行個體的長度與布局中聲明的長度不比對“(C#的string到C/C++的char 數組不會,但是C#char[]到C/C++的char數組會有此異常),是以, 我們要定義相同長度的數組才能正常工作(C#數組長度更大的時候,會忽略多餘的部分)