How to marshal an unknown length C++ string to C# using its pointer?

痞子三分冷 提交于 2019-12-20 06:27:45

问题


I'm trying to marshal a dynamically allocated char array in a struct to C#. The struct has a pointer to the array. The problem is the char array contains multiple null terminated strings and the last string is terminated by two consecutive null chars.

If I try to marshal it as LPStr I will get only de first string in the "list".

I tried using UnmanagedMemoryStream but it requires to know the length of the array.

Is there a way to read the bytes as a stream without knowing the length of the array? (Aside from using a n length byte buffer and keep increasing the pointer until two consecutive null terminating chars are found).


回答1:


As suggested by Hans Passant, the only way is to Marshal.ReadByte(), so in the end you have to read the memory multiple times (PtrToStringAnsi reads it at least twice plus the one we do to find where the next string begins).

public static string[] IntPtrToStringArrayAnsi(IntPtr ptr)
{
    var lst = new List<string>();

    do
    {
        lst.Add(Marshal.PtrToStringAnsi(ptr));

        while (Marshal.ReadByte(ptr) != 0)
        {
            ptr = IntPtr.Add(ptr, 1);
        }

        ptr = IntPtr.Add(ptr, 1);
    }
    while (Marshal.ReadByte(ptr) != 0);

    // See comment of @zneak
    if (lst.Count == 1 && lst[0] == string.Empty)
    {
        return new string[0];
    }

    return lst.ToArray();
}



回答2:


An alternate version, which avoids a second sweep over the array

private static List<string> IntPtrToStringArrayAnsi(IntPtr ptr)
{
    var lst = new List<string>();
    while (true)
    {
        var str = Marshal.PtrToStringAnsi(ptr);
        if (!string.IsNullOrEmpty(str))
        {
            lst.Add(str);
            ptr += str.Length + 1;
        }
        else
            break;
    }

    return lst.ToArray();
}


来源:https://stackoverflow.com/questions/51218293/how-to-marshal-an-unknown-length-c-string-to-c-sharp-using-its-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!