Вопрос

У меня определен следующий метод:

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.Когда я присвоил луч переменной выводаRecord, содержимое строки равно длине буфера;однако существует число NUL (Char 0) для заполнения оставшейся части строки до тех пор, пока она не достигнет поля RecordInformation.Length.Если я изменю последний параметр в списке параметров UnmanagedMethod на bufferSize, выходная строка превратится в символы NUL.

Я неправильно делаю маршалинг или есть ли способ после создания строки из массива байтов удалить символы NUL?

Спасибо

Это было полезно?

Решение

Я не вижу ничего плохого в вашем примере.

Вероятно, вы захотите отметить, что строки .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, и последнее приведет к абв.

Также обратите внимание, что последний метод потребует от вас сначала проверить наличие NUL-символов, на тот случай, если строка содержит всю позицию буфера и вообще не было NUL-символов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top