来自C#中Marshal.Copy的NUL字符

时间:2009-07-07 17:13:28

标签: c# unmanaged marshalling

我定义了以下方法:

internal string GetInformation(string recordInformation)
{
    int bufferSize = GetBufferSize(recordInformation);

    string outputRecord;
    IntPtr output = Marshal.AllocHGlobal(bufferSize);

    try
    {
        _returnCode = UnmanagedMethod(recordInformation, output, recordInformation.Length);
        byte[] outputData = new byte[bufferSize];
        Marshal.Copy(output, outputData, 0, bufferSize);
        outputRecord = ASCIIEncoding.ASCII.GetString(outputData, 0, bufferSize);
    }
    finally
    {
        Marshal.FreeHGlobal(output);
    }

    return outputRecord;
}

在此方法中,将提供的字符串(recordInformation)传递给用C(UnmanagedMethod)编写的方法。根据我对此方法的文档,bufferSize设置正确;但是,Marshal.Copy会创建一个大小为recordInformation.Length的数组。当我将光线分配给outputRecord变量时,字符串的内容是bufferSize的长度;但是,有一些NUL(字符0)填充字符串的其余部分,直到它到达recordInformation.Length字段。如果我将UnmanagedMethod参数列表中的最后一个参数更改为bufferSize,则输出字符串将变为NUL字符。

我是否正在编组错误或者是否在从字节数组创建字符串后删除NUL字符?

由于

1 个答案:

答案 0 :(得分:1)

我认为你的例子没有任何问题。

你可能想要注意.NET字符串可以包含NUL / NULL字符 - 但实际上,字符的值只有0('\ 0'或'\ x00')。

您可以通过替换或遍历字符串来清除字符,并将所有内容保留在第一个NUL之前。很可能你会想要后者,因为这是C中零终止字符串的典型特征。

这是一个快速示例(控制台),说明在任何一种情况下会发生什么。

string sTest1 = "abc\0\0def";

string sTest2 = sTest1.Replace("\0", "");
Console.WriteLine(sTest2);

int iLocation = sTest1.IndexOf('\0');
string sTest3 = "";
if (iLocation >= 0)
{
    sTest3 = sTest1.Substring(0, iLocation);
}
else
{
    sTest3 = sTest1;
}
Console.WriteLine(sTest3);

Console.ReadLine();

前者将导致 abcdef ,后者将导致 abc

另请注意,后一种方法将要求您首先检查NUL字符,以防字符串包含整个缓冲区位置且根本没有NUL字符。