我在编码指向字符串数组的指针时遇到了一些问题。它看起来像这样无害:
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 并逐一提取字符串。
最佳答案
除了一个非常基本的字符串之外,编码任何东西都是复杂的,并且充满了难以发现的副作用。通常最好在结构定义中使用安全/简单的路由,并添加一些包装器属性来稍微整理一下。
在这种情况下,我会使用 IntPtr 数组,然后添加一个将它们转换为字符串的包装器属性
[StructLayout(LayoutKind.Sequential)]
public struct UnmanagedStruct
{
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr, SizeConst=100)]
public IntPtr[] listOfStrings;
public IEnumerable<string> Strings { get {
return listOfStrings.Select(x =>Marshal.PtrToStringAnsi(x));
}
}
关于c# - 将指针编码到字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1323797/