编组指针字符串数组(Marshaling pointer to an array of string

2019-08-02 08:43发布

我有一些麻烦,封送指针字符串数组。 它看起来无害的像这样:

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并提取字符串一个接一个。

Answer 1:

编组什么,但一个非常基本的字符串是复杂和充满侧的情况下是很难被发现。 它通常是最好的去与在结构定义的安全/简约路线,并添加一些包装性能整理了一点东西。

在这种情况下,我会去的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));
    }
}


Answer 2:

行..我好像得到它的工作。 应当编组作为IntPtr的[]

这似乎工作:

[StructLayout(LayoutKind.Sequential)] 
public struct UnmanagedStruct 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=100)] 
    public IntPtr[] listOfStrings; 
}

for (int i = 0; i < 100; ++i)
{
    if (listOfstrings[i] != IntPtr.Zero)
        Console.WriteLine(Marshal.PtrToStringAnsi(listOfStrings[i]));
}    


文章来源: Marshaling pointer to an array of strings