如何向函数发送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,代码更改最少,所以我需要自己初始化缓冲区。
谢谢,
答案 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。