如何使用其指针将未知长度的C ++字符串编组为C#? [英] How to marshal an unknown length C++ string to C# using its pointer?

查看:87
本文介绍了如何使用其指针将未知长度的C ++字符串编组为C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将结构中动态分配的char数组编组为C#.该结构具有指向数组的指针.问题在于char数组包含多个以null终止的字符串,而最后一个字符串由两个连续的null字符终止.

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.

如果我尝试将其封送为LPStr,则只会在列表"中获得第一个字符串.

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

我尝试使用UnmanagedMemoryStream,但它需要知道数组的长度.

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

是否有一种方法可以在不知道数组长度的情况下将字节作为流读取? (除了使用n长度的字节缓冲区外,还要不断增加指针,直到找到两个连续的null终止字符为止.)

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).

推荐答案

正如汉斯·帕桑特(Hans Passant)所建议的那样,唯一的方法是访问Marshal.ReadByte(),因此最终您必须多次读取内存(PtrToStringAnsi读取它至少要加上两次,我们要查找下一个字符串从何处开始.

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();
}

这篇关于如何使用其指针将未知长度的C ++字符串编组为C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆