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

时间:2022-11-17 07:30:13

I have the following method defined:

我定义了以下方法:

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

In this method, a provided string (recordInformation) is passed to a method written in C (UnmanagedMethod). Based on the documentation I have for this method, the bufferSize is setup properly; however, Marshal.Copy creates an array the size of recordInformation.Length instead. When I assigned the ray to the outputRecord variable, the content of the string is the length of the bufferSize; however, there is a number of NUL (Char 0) to fill the remainder of the string until it hits the recordInformation.Length field. If I change the last parameter in the UnmanagedMethod parameter list to bufferSize, the output string turns into nothing but NUL characters.

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

Am I doing the marshaling wrong or is there a way after the string has been created from the byte array to remove the NUL characters?

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

Thanks

1 个解决方案

#1


I don't see anything wrong with your example.

我没有看到你的例子有什么问题。

You'll probably want to note that .NET strings can contain NUL/NULL characters- but really, characters that just have the value 0 ('\0' or '\x00').

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

You can scrub out the characters by doing a replace or walking over the string and keep everything before the first NUL. Most likely you will want the latter, as this is typical for zero-terminated strings in C.

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

Here's a quick example (Console) that illustrates what will happen in either case.

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

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

The former will result in abcdef, and the latter will result in abc.

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

Also note that the latter method will require you to check for NUL characters first, just in case the string contains the entire buffer location and there were no NUL characters at all.

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

#1


I don't see anything wrong with your example.

我没有看到你的例子有什么问题。

You'll probably want to note that .NET strings can contain NUL/NULL characters- but really, characters that just have the value 0 ('\0' or '\x00').

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

You can scrub out the characters by doing a replace or walking over the string and keep everything before the first NUL. Most likely you will want the latter, as this is typical for zero-terminated strings in C.

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

Here's a quick example (Console) that illustrates what will happen in either case.

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

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

The former will result in abcdef, and the latter will result in abc.

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

Also note that the latter method will require you to check for NUL characters first, just in case the string contains the entire buffer location and there were no NUL characters at all.

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