将指针编组到字符串数组
我在整理指向字符串数组的指针时遇到一些问题。它看起来像这样无害:
typedef struct
{
char* listOfStrings[100];
} UnmanagedStruct;
这实际上嵌入到另一个结构中,如下所示:
typedef struct
{
UnmanagedStruct umgdStruct;
} Outerstruct;
非托管代码回调到托管代码并将 Outerstruct 作为已分配内存并填充值的 IntPtr 返回。
托管世界:
[StructLayout(LayoutKind.Sequential)]
public struct UnmanagedStruct
{
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr, SizeConst=100)]
public string[] listOfStrings;
}
[StructLayout(LayoutKind.Sequential)]
public struct Outerstruct
{
public UnmanagedStruct ums;
}
public void CallbackFromUnmanagedLayer(IntPtr outerStruct)
{
Outerstruct os = Marshal.PtrToStructure(outerStruct, typeof(Outerstruct));
// The above line FAILS! it throws an exception complaining it cannot marshal listOfStrings field in the inner struct and that its managed representation is incorrect!
}
如果我将 listOfStrings 更改为简单的 IntPtr 那么Marshal.PtrToStructure 可以工作,但现在我无法破解 listOfStrings 并一一提取字符串。
I am having some trouble marshaling a pointer to an array of strings. It looks harmless like this:
typedef struct
{
char* listOfStrings[100];
} UnmanagedStruct;
This is actually embedded inside another structure like this:
typedef struct
{
UnmanagedStruct umgdStruct;
} Outerstruct;
Unmanaged code calls back into managed code and returns Outerstruct as an IntPtr with memory allocated and values filled in.
Managed world:
[StructLayout(LayoutKind.Sequential)]
public struct UnmanagedStruct
{
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr, SizeConst=100)]
public string[] listOfStrings;
}
[StructLayout(LayoutKind.Sequential)]
public struct Outerstruct
{
public UnmanagedStruct ums;
}
public void CallbackFromUnmanagedLayer(IntPtr outerStruct)
{
Outerstruct os = Marshal.PtrToStructure(outerStruct, typeof(Outerstruct));
// The above line FAILS! it throws an exception complaining it cannot marshal listOfStrings field in the inner struct and that its managed representation is incorrect!
}
If I change listOfStrings to simply be an IntPtr then Marshal.PtrToStructure works but now I am unable to rip into listOfStrings and extract the strings one by one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除了非常基本的字符串之外,对任何内容进行编组都是复杂的,并且充满了难以发现的副作用。通常最好在结构定义中采用安全/简单的路线,并添加一些包装属性来整理一些东西。
在这种情况下,我将使用 IntPtr 数组,然后添加一个包装器属性,将它们转换为字符串
Marshalling anything but a very basic string is complex and full of side cases that are hard to spot. It's usually best to go with the safe / simple route in the struct definition and add some wrapper properties to tidy things up a bit.
In this case I would go with the array of IntPtr and then add a wrapper property that converts them to strings
好吧..我似乎已经开始工作了。它应该被封送为 IntPtr[]
这似乎有效:
OK.. I seem to have got it to work. It should be marshaled as IntPtr[]
This seems to work: