0

次のメソッドが定義されています。

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 のサイズの配列を作成します。ray を outputRecord 変数に割り当てたとき、文字列の内容は bufferSize の長さです。ただし、recordInformation.Length フィールドに到達するまで、文字列の残りを埋める NUL (文字 0) がいくつかあります。UnmanagedMethod パラメータ リストの最後のパラメータを bufferSize に変更すると、出力文字列は NUL 文字だけになります。

マーシャリングが間違っていますか、または文字列がバイト配列から作成された後に NUL 文字を削除する方法はありますか?

ありがとう

4

1 に答える 1

1

あなたの例には何も問題はありません。

おそらく、.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になり、後者はabcになります。

また、後者の方法では、最初に NUL 文字をチェックする必要があることに注意してください。これは、文字列にバッファの場所全体が含まれていて、NUL 文字がまったくない場合に備えてです。

于 2009-07-07T17:40:00.083 に答える