2009-07-07 6 views
0

je la méthode suivante: définiecaractères NUL de Marshal.Copy en 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; 
} 

Dans cette méthode, une chaîne fournie (recordInformation) est passé à une méthode écrite en C (UnmanagedMethod). Basé sur la documentation que j'ai pour cette méthode, le bufferSize est configuré correctement; Toutefois, Marshal.Copy crée un tableau de la taille de recordInformation.Length à la place. Lorsque j'ai affecté le rayon à la variable outputRecord, le contenu de la chaîne est la longueur de la bufferSize; cependant, il existe un certain nombre de NUL (Char 0) pour remplir le reste de la chaîne jusqu'à ce qu'elle atteigne le champ recordInformation.Length. Si je change le dernier paramètre de la liste de paramètres UnmanagedMethod en bufferSize, la chaîne de sortie ne se transforme en rien d'autre que des caractères NUL. Est-ce que je fais le marshaling mal ou est-il un moyen après la chaîne a été créée du tableau d'octets pour enlever les caractères NUL?

Merci

+0

Quelle méthode non gérée utilisez-vous? Il est difficile de dire quelle serait la meilleure façon d'être maréchal sans pouvoir lire les spécifications autochtones. Est-ce une méthode API, ou quelque chose de personnalisé? –

+0

La méthode non managée est une méthode d'une API tierce. La documentation de l'API est tout en C et la signature de la méthode (en C) est 'int UnmanagedMethod (char * inputstring, char * sortiestring, int inputlength)'. La chaîne outputRecord est créée correctement autre que les caractères NUL à la fin de la chaîne. – JamesEggers

+0

J'ai demandé à l'API tierce partie et ils ne connaissent pas C# et ne sont pas en mesure de fournir autre chose qu'un exemple non-travail/non-compilation. – JamesEggers

Répondre

1

Je ne vois rien de mal dans votre exemple.

Vous voudrez probablement noter que les chaînes .NET peuvent contenir des caractères NUL/NULL, mais en réalité, des caractères qui ont juste la valeur 0 ('\ 0' ou '\ x00').

Vous pouvez effacer les caractères en faisant un remplacement ou en marchant sur la chaîne et conserver tout avant le premier NUL. Très probablement, vous voudrez ce dernier, car cela est typique pour les chaînes terminées par zéro dans C.

Voici un exemple rapide (console) qui illustre ce qui se passera dans les deux cas.

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

L'ancien se traduira par abcdef, et celui-ci se traduira par abc. Notez également que la dernière méthode exigera que vous vérifiiez d'abord les caractères NUL, juste au cas où la chaîne contienne tout l'emplacement du tampon et qu'il n'y ait aucun caractère NUL.

+0

Je devrais ajouter que vous pouvez aussi simplement scanner le tampon outputData pour le premier octet égal à zéro pour tronquer aussi la chaîne. – meklarian

+0

J'ai essayé de faire le Replace ("\ 0", "") à la fin de la méthode et j'obtiens toujours les caractères NUL dans la chaîne que je retourne dans la méthode. – JamesEggers

+0

avez-vous retourné le résultat de l'appel? ex. [return outputRecord.Replace ("\ 0", "");]. chaîne Replace() renvoie une nouvelle chaîne et ne modifie pas la chaîne d'origine. – meklarian