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];
    }
}

这是我收到的错误:

您只能在固定语句初始化程序中获取未固定表达式的地址

最初我使用的是一个 USB 传输 dll,它在建立连接时接收并初始化一个缓冲区的 *byte 指针。现在我想用不同的平台更改该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 回答