這篇是講述PINVOKE中應對各種指針的方法包括普通指針字符串指針二級指針指針數組函數指針結構體指針篇幅估計有點長大家耐心點看嘿嘿~~
第一普通指針包括char *short *int *__int *這些指針進行平台調用是都對應的IntPtr類型然後使用MarshalReadXXX()系列函數讀取就可寫時使用MarshalWriteXXX()系列函數就行
:
static int test = ;
int * __stdcall ReadInt()
{
return &test;
}
c#:注意MarshalReadXXX()系列函數的使用
[DllImport(TestDll)]
public static extern IntPtr ReadInt();
//##############################
IntPtr p = ReadInt();
ConsoleWriteLine(MarshalReadInt(p));
IntPtr p = ReadUint();
ConsoleWriteLine(ConvertToUInt(MarshalReadInt(p)));
第二字符串指針上一篇已經有過討論可以使用marshalAs返回值當然也可以用MarshalPtrToStringAuto()來讀取字符串個人推薦第一個
c++:
static char * test = you are very very bad bad girl gaga!;
char * __stdcall ReadString()
{
return test;
}
static wchar_t * test = TEXT(you are very very bad bad girl gaga!);
wchar_t * __stdcall ReadStringW()
{
return test;
}
:注意MarshalPtrToStringAuto()函數的使用
[DllImport(TestDll)]
[return: MarshalAs(UnmanagedTypeLPStr)]
public static extern string ReadString();
[DllImport(TestDll)]
public static extern IntPtr ReadStringW();
//#########################
ConsoleWriteLine(ReadString());
IntPtr p = ReadStringW();
ConsoleWriteLine(MarshalPtrToStringAuto(p));
第三函數指針C#的委托就對應的__stdcall調用協議的函數指針前面也有討論
c++:
typedef void (__stdcall * FunctionPoint)(void);
void __stdcall TestFunction(){printf(you are very very bad bad girl gaga!\n);}
FunctionPoint __stdcall GetFunctionPointer()
{
return TestFunction;
}
c#:
public delegate void FunctionPointer();
[DllImport(TestDll)]
public static extern FunctionPointer GetFunctionPointer();
//#########################
FunctionPointer pointer = GetFunctionPointer();
pointer();
第四指針的指針也就是二級指針要使用MarshalReadIntPtr()來讀取
c++:
static int test = ;
static int * test = &test;
int ** __stdcall ReadPoint()
{
return &test;
}
[DllImport(TestDll)]
public static extern IntPtr ReadPoint();
//#########################
IntPtr p = ReadPoint();
IntPtr p = MarshalReadIntPtr(p);
int test = MarshalReadInt(p);
ConsoleWriteLine(test);
第五指針數組沒有太直接的方法因為所有指針都是BYTE所以這裡我是這麼讀的
C++:
static int test = ;
static int test = ;
static int * test[] = {};
int ** __stdcall ReadPointArray()
{
test[] = &test;
test[] = &test;
test[] = &test;
return test;
}
C#:
[DllImport(TestDll)]
public static extern IntPtr ReadPointArray();
//#########################
IntPtr p = ReadPointArray();
int test = pToInt();
ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(p)));
ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(new IntPtr(test + ))));
ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(new IntPtr(test + ))));
ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(new IntPtr(test + ))));
最後: 結構體的指針用C#建立對應C++的結構體並使用 [StructLayout(LayoutKindSequential)]屬性
使用MarshalPtrToStructure()讀取
c++:
struct Test
{
int test;
};
static Test test;
Test * __stdcall ReadStruct()
{
testtest = ;
return &test;
}
c#:
[StructLayout(LayoutKindSequential)]
public struct Test
{
public int test;
}
[DllImport(TestDll)]
public static extern IntPtr ReadStruct();
//#########################
IntPtr p = ReadStruct();
Test test = (Test)MarshalPtrToStructure(ptypeof(Test));
ConsoleWriteLine(testtest);
From:http://tw.wingwit.com/Article/program/net/201311/12123.html