如何通过C#中的函数为数组的指针参数分配内存

时间:2012-04-20 12:07:01

标签: c#

如何向函数发送ref指针并将地址返回到C#中的已分配内存。以下代码无法编译:

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在建立连接时接收并初始化了缓冲区的*字节指针。现在我想用不同的平台更改该DLL,代码更改最少,所以我需要自己初始化缓冲区。

谢谢,

3 个答案:

答案 0 :(得分:7)

如果您正在调用的非托管代码需要长时间指向缓冲区 ,那么您不希望首先传递托管缓冲区。为什么?因为托管缓冲区必须长时间固定,这会使垃圾收集器做额外的工作。

相反,使用非托管内存分配器分配非托管缓冲区,并将指针传递给非托管代码。

答案 1 :(得分:3)

如上所述,您可以使用fixed statement固定一个对象,但这对您不起作用,因为您通过ref参数返回指针。如果您尝试使用fixed语句,代码将编译,但生成的指针在使用时可能无效。这是因为一旦退出固定语句块,就会取消固定该对象,从而允许其地址随时更改。

在这种情况下,您需要使用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.
    }
}

答案 2 :(得分:0)

编译器告诉您需要使用fixed Statement