这篇是讲述PINVOKE中应对各种指针的方法包括普通指针字符串指针二级指针指针数组函数指针结构体指针篇幅估计有点长大家耐心点看嘿嘿~~ 第一普通指针包括char *short *int *__int *这些指针进行平台调用是都对应的IntPtr类型然后使用MarshalReadXXX()系列函数读取就可写时使用MarshalWriteXXX()系列函数就行 : staticinttest=;int*__stdcallReadInt() { return&test; }
c#:注意MarshalReadXXX()系列函数的使用 [DllImport(TestDll)]publicstaticexternIntPtrReadInt(); //############################## IntPtrp=ReadInt(); ConsoleWriteLine(MarshalReadInt(p)); IntPtrp=ReadUint(); ConsoleWriteLine(ConvertToUInt(MarshalReadInt(p)));
第二字符串指针上一篇已经有过讨论可以使用marshalAs返回值当然也可以用MarshalPtrToStringAuto()来读取字符串个人推荐第一个 c++: staticchar*test=youareveryverybadbadgirlgaga!;char*__stdcallReadString() { returntest; }
staticwchar_t*test=TEXT(youareveryverybadbadgirlgaga!); wchar_t*__stdcallReadStringW() { returntest; } :注意MarshalPtrToStringAuto()函数的使用 [DllImport(TestDll)][return:MarshalAs(UnmanagedTypeLPStr)] publicstaticexternstringReadString();
[DllImport(TestDll)] publicstaticexternIntPtrReadStringW(); //######################### ConsoleWriteLine(ReadString());
IntPtrp=ReadStringW(); ConsoleWriteLine(MarshalPtrToStringAuto(p));
第三函数指针C#的委托就对应的__stdcall调用协议的函数指针前面也有讨论 c++: typedefvoid(__stdcall*FunctionPoint)(void);void__stdcallTestFunction(){printf(youareveryverybadbadgirlgaga!\n);} FunctionPoint__stdcallGetFunctionPointer() { returnTestFunction; }
c#: publicdelegatevoidFunctionPointer();[DllImport(TestDll)] publicstaticexternFunctionPointerGetFunctionPointer(); //######################### FunctionPointerpointer=GetFunctionPointer(); pointer();
第四指针的指针也就是二级指针要使用MarshalReadIntPtr()来读取 c++: staticinttest=;staticint*test=&test; int**__stdcallReadPoint() { return&test; } [DllImport(TestDll)]publicstaticexternIntPtrReadPoint(); //######################### IntPtrp=ReadPoint(); IntPtrp=MarshalReadIntPtr(p); inttest=MarshalReadInt(p); ConsoleWriteLine(test);
第五指针数组没有太直接的方法因为所有指针都是BYTE所以这里我是这么读的 C++: staticinttest=;staticinttest=; staticint*test[]={}; int**__stdcallReadPointArray() { test[]=&test; test[]=&test; test[]=&test; returntest; }
C#: [DllImport(TestDll)]publicstaticexternIntPtrReadPointArray(); //######################### IntPtrp=ReadPointArray(); inttest=pToInt(); ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(p))); ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(newIntPtr(test+)))); ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(newIntPtr(test+)))); ConsoleWriteLine(MarshalReadInt(MarshalReadIntPtr(newIntPtr(test+))));
最后: 结构体的指针用C#建立对应C++的结构体并使用 [StructLayout(LayoutKindSequential)]属性 使用MarshalPtrToStructure()读取 c++: structTest{ inttest; };
staticTesttest; Test*__stdcallReadStruct() { testtest=; return&test; }
c#: [StructLayout(LayoutKindSequential)]publicstructTest { publicinttest; }
[DllImport(TestDll)] publicstaticexternIntPtrReadStruct(); //#########################
IntPtrp=ReadStruct(); Testtest=(Test)MarshalPtrToStructure(ptypeof(Test)); ConsoleWriteLine(testtest); |