2009-07-07 5 views
0

Ich habe folgende Verfahren festgelegt:NUL Zeichen aus Marshal.Copy in C#

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 diesem Verfahren wird ein vorgegebener String (recordInformation) ist auf ein Verfahren geführt, in C (UnmanagedMethod) geschrieben. Basierend auf der Dokumentation, die ich für diese Methode habe, ist die Puffergröße richtig eingerichtet. Marshal.Copy erstellt jedoch stattdessen ein Array mit der Größe von recordInformation.Length. Wenn ich den Ray der Variable outputRecord zugewiesen habe, entspricht der Inhalt der Zeichenfolge der Länge der pufferSize. Allerdings gibt es eine Anzahl von NUL (Char 0), um den Rest der Zeichenfolge zu füllen, bis es das recordInformation.Length-Feld trifft. Wenn ich den letzten Parameter in der UnmanagedMethod-Parameterliste in pufferSize ändere, wird der Ausgabe-String in nichts anderes als NUL-Zeichen umgewandelt.

Mache ich das Marshalling falsch oder gibt es eine Möglichkeit, nachdem die Zeichenfolge aus dem Bytearray erstellt wurde, um die NUL-Zeichen zu entfernen?

Danke

+0

Welche nicht verwaltete Methode verwenden Sie? Es ist schwer zu sagen, was der beste Weg zum Marshal wäre, ohne die native Spezifikation lesen zu können. Ist es eine API-Methode oder etwas Brauchbares? –

+0

Die nicht verwaltete Methode ist eine Methode von einer API von Drittanbietern. Die API-Dokumentation ist alles in C und die Methodensignatur (in C) ist 'int UnmanagedMethod (char * inputstring, char * outputstring, int inputlength)'. Die outputRecord-Zeichenfolge wird mit Ausnahme der NUL-Zeichen am Ende der Zeichenfolge korrekt erstellt. – JamesEggers

+0

Ich habe die 3rd Party API angefragt und sie kennen C# nicht und können nichts anderes als ein nicht arbeitendes/nicht kompilierendes Beispiel liefern. – JamesEggers

Antwort

1

Ich sehe nichts falsch mit Ihrem Beispiel.

Sie werden wahrscheinlich feststellen, dass .NET-Strings NULL/NULL-Zeichen enthalten können - aber wirklich, Zeichen, die nur den Wert 0 haben ('\ 0' oder '\ x00').

Sie können die Zeichen schrubben, indem Sie die Zeichenfolge ersetzen oder übergehen und alles vor der ersten NUL behalten. Höchstwahrscheinlich werden Sie Letzteres wollen, da dies typisch für Null-terminierte Strings in C ist.

Hier ist ein kurzes Beispiel (Konsole), das veranschaulicht, was in jedem Fall passieren wird.

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

Erstere in abcdef führen wird, und letztere in abc führen.

Beachten Sie auch, dass bei der letzteren Methode zuerst nach NUL-Zeichen gesucht werden muss, für den Fall, dass die Zeichenfolge den gesamten Pufferspeicherort enthält und überhaupt keine NUL-Zeichen vorhanden sind.

+0

Ich sollte hinzufügen, dass Sie auch nur den outputData-Puffer für das erste Byte gleich Null durchsuchen können, um die Zeichenfolge auch zu schneiden. – meklarian

+0

Ich habe versucht, die Replace ("\ 0", "") am Ende der Methode zu tun, und ich bekomme immer noch die NUL-Zeichen in der Zeichenfolge, die ich in der Methode zurückgebe. – JamesEggers

+0

haben Sie das Ergebnis des Anrufs zurückgegeben? Ex. [return outputRecord.Replace ("\ 0", "");]. string's Replace() gibt eine neue Zeichenkette zurück und ändert nicht die ursprüngliche Zeichenkette. – meklarian

Verwandte Themen