caratteri NUL da Marshal.Copy in C #
-
11-09-2019 - |
Domanda
Ho il seguente metodo definito:
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 questo metodo, una stringa fornita (recordInformation) è passato a un metodo scritto in C (UnmanagedMethod). Sulla base della documentazione che ho per questo metodo, il bufferSize è impostato correttamente; tuttavia, Marshal.Copy crea una matrice delle dimensioni di recordInformation.Length invece. Quando ho assegnato il raggio alla variabile outputRecord, il contenuto della stringa è la lunghezza del bufferSize; Tuttavia, v'è un certo numero di NUL (Char 0) per riempire il resto della stringa fino a raggiungere il campo recordInformation.Length. Se cambio l'ultimo parametro nell'elenco dei parametri UnmanagedMethod al bufferSize, la stringa di output si trasforma in nulla, ma caratteri NUL.
Sto facendo la marshalling sbagliato o c'è un modo dopo la stringa è stata creata dalla matrice di byte per rimuovere i caratteri NUL?
Grazie
Soluzione
Non vedo niente di sbagliato con il vostro esempio.
Probabilmente si vorrà notare che le stringhe .NET possono contenere NUL / NULL personaggi- ma in realtà, i personaggi che hanno solo il valore 0 ( '\ 0' o '\ x00').
È possibile macchia i personaggi facendo una sostituzione o camminare sulla corda e tenere tutto prima del primo NUL. Molto probabilmente si desidera che questi ultimi, in quanto questo è tipico per terminata da zero stringhe in C.
Ecco un rapido esempio (Console) che illustra ciò che accadrà in entrambi i casi.
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();
Il primo si tradurrà in abcdef , e quest'ultimo si tradurrà in abc .
Si noti inoltre che quest'ultimo metodo richiederà di verificare la presenza di caratteri NUL prima, nel caso in cui la stringa contiene l'intero percorso di buffer e non c'erano caratteri NUL a tutti.