我有其中一个结构的定义如下一个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中的全局变量的指针。如果你需要返回一个指针,就这样做。作为返回值。我不认为你完全理解你在做什么。我想帮助你理解。 –