1

文字列を操作する C++ コードと対話する C# コードがあります。

静的ヘルパー クラスに次のコードがあります。

internal static unsafe byte* GetConstNullTerminated(string text, Encoding encoding)
{
    int charCount = text.Length;
    fixed (char* chars = text)
    {
        int byteCount = encoding.GetByteCount(chars, charCount);
        byte* bytes = stackalloc byte[byteCount + 1];
        encoding.GetBytes(chars, charCount, bytes, byteCount);
        *(bytes + byteCount) = 0;
        return bytes;
    }
}

ご覧のとおり、stackallocキーワードで作成されたバイトへのポインターを返します。
ただし、C# 仕様 18.8 から:

関数メンバーの実行中に作成されたすべてのスタック割り当てメモリ ブロックは、その関数メンバーが戻るときに自動的に破棄されます。

メソッドが戻るとすぐにポインターが実際に無効になるということですか?

メソッドの現在の使用法:

byte* bytes = StringHelper.GetConstNullTerminated(value ?? string.Empty, Encoding);
DirectFunction(NativeMethods.SCI_SETTEXT, UIntPtr.Zero, (IntPtr) bytes);

コードを次のように変更する必要があります

...
int byteCount = encoding.GetByteCount(chars, charCount);
byte[] byteArray = new byte[byteCount + 1];
fixed (byte* bytes = byteArray)
{
    encoding.GetBytes(chars, charCount, bytes, byteCount);
    *(bytes + byteCount) = 0;
}
return byteArray;

メソッドfixedにポインターを渡すために、返された配列を再度使用しますか?DirectFunction

使用回数を最小限に抑えようとしています(およびofの他のオーバーロードのステートメントをfixed含む)。fixedGetByteCount()GetBytes()Encoding

tl;dr

  1. メソッドが戻るとすぐにポインターは無効になりますか? に渡された時点で無効DirectFunction()ですか?

  2. fixedもしそうなら、タスクを達成するために最も少ないステートメントを使用する最良の方法は何ですか?

4

2 に答える 2