我有其中一個結構的定義如下一個C++機DLL:在C++ DLL作爲Pinvoking不復制整個字符串
typedef struct
{
int x;
int y;
unsigned short* orange;
}SET_PROFILE;
和一個功能:
extern "C" _declspec(dllexport) void modifyClass(SET_PROFILE** input)
{
*input = &globPro;
}
其中globPro是一個全局SET_PROFILE類型的對象,其成員橙色是「ABC」。
我已經重新定義該結構上的C#側爲一類:
[StructLayout(LayoutKind.Sequential)]
public class SET_PROFILE
{
public int x;
public int y;
public String orange;
}
和pinvoking功能:
[DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void modifyClass(out IntPtr input);
當我調用此函數,然後marhal回以下結構:
IntPtr classPtr = IntPtr.Zero;
classPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SET_PROFILE)));
modifyClass(out classPtr);
profile1 = (SET_PROFILE)Marshal.PtrToStructure(classPtr, typeof(SET_PROFILE));
現在,profile1的orange meber只有「A」而不是「ABC」。它與如何使用指針進行復制有關。但是我不能修改C++函數。 是因爲我使用了一個字符串作爲C#類的成員而不是unsigned short []。我也嘗試過,但失敗了。
這是一個Unicode字符串,默認編組假設'字符*'。這就是爲什麼你只得到單個字母,'A'之後有一個額外的二進制零。使用CharSet = CharSet.Unicode或Marshal.PtrToStringUni()。 –
謝謝。我編輯的dll導入包括CharSet = CharSet.Unicode,但它仍然顯示一個字母。我不能使用Marshal.PtrToStringUni(),因爲我作爲一個整體處理類而不僅僅是它的字符串成員。 –
你做錯了。您應該將結構體的值複製到調用者的變量中,並通過引用傳遞。您不應該返回一個指向DLL中的全局變量的指針。如果你需要返回一個指針,就這樣做。作爲返回值。我不認爲你完全理解你在做什麼。我想幫助你理解。 –