NUL-символы из Marshal.Copy в C#
-
11-09-2019 - |
Вопрос
У меня определен следующий метод:
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-символов.