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

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top