2

C# で、ref ポインターを関数に送信し、割り当てられたメモリにアドレスを返すにはどうすればよいですか。次のコードはコンパイルされません。

class Test
{
    public byte [] byteArr_1 = new byte [1024];
    //public byte* P_byte;

    public unsafe void SetAddress(ref byte* p_b)
    {
        p_b = &byteArr_1[0];
    }
}

これは私が受け取るエラーです:

固定ステートメント初期化子内の固定されていない式のアドレスのみを取得できます

もともと、接続が確立されたときにバッファの *byte ポインタを受信して​​初期化する USB 送信 dll を使用していました。ここで、コードの変更を最小限に抑えて別のプラットフォームでその dll を変更したいので、自分でバッファーを初期化する必要があります。

ありがとう、

4

3 に答える 3

7

呼び出しているアンマネージ コードが長い間バッファーへのポインターを必要とする場合、そもそもマネージ バッファーを渡したくありません。なんで?マネージ バッファーを長時間固定する必要があり、ガベージ コレクターが余分な作業を行うためです。

代わりに、アンマネージ メモリ アロケーターを使用してアンマネージ バッファーを割り当て、それへのポインターをアンマネージ コードに渡します。

于 2012-04-20T15:08:39.517 に答える
3

前述のように、fixedステートメントを使用してオブジェクトを固定できますが、refパラメーターを介してポインターを返すため、これは機能しません。固定ステートメントを使用しようとすると、コードはコンパイルされますが、結果のポインターは、使用されるまでに無効になる可能性があります。これは、固定ステートメントブロックが終了すると、オブジェクトの固定が解除され、アドレスをいつでも変更できるためです。

この場合、GCHandle.Allocを使用してバッファーを固定する必要があります。

class Test
{
    public byte [] byteArr_1 = new byte [1024];
    private GCHandle pinned;
    //public byte* P_byte;

    public unsafe void SetAddress(ref byte* p_b)
    {
        pinned = GCHandle.Alloc(byteArr_1, GCHandleType.Pinned);
        p_b = (byte*)pinned.AddrOfPinnedObject();
        // NOTE: Don't forget to free the GCHandle at some point via GCHandle.Free!
        // Remember that once this handle is freed, the pointer should not be used in any way.
    }
}
于 2012-04-20T12:17:40.437 に答える
0

コンパイラは、修正された Statementを使用する必要があることを伝えています。

于 2012-04-20T12:14:23.553 に答える