将字节指针传递给CLR函数

时间:2014-12-16 14:28:49

标签: c# .net c#-4.0

为了练习,我试图用C#在堆栈上分配一个字节缓冲区并将其传递给Socket.Send

byte *buffer = stackalloc byte[256];

// fill buffer

socket.Send(buffer, 3 + _body.Length + 1, SocketFlags.None);

但是Visual Studio吐出了这条消息:

  

错误27参数1:无法转换为' byte *'到' byte []'

有没有办法将指针转换为数组而不分配新数组

3 个答案:

答案 0 :(得分:4)

不,没有。想一想:通用指针缺少附加到每个.NET对象的元数据,因此垃圾收集器永远无法正确处理数组。想象一下,您将“数组”交给代码,然后将其存储在实例字段中 - 当您释放其背后的内存时,代码(已验证的托管代码)将失败(在stackalloc的情况下,当包含方法结束)。

如果你想要一个托管数组,你将不得不分配一个托管数组,无处可去。

答案 1 :(得分:2)

在不安全的代码上下文中使用stackalloc关键字来在堆栈上分配内存块。

您的代码是纯托管代码,您应该使用new而不是stackalloc。

byte[] buffer = new byte[256];

// fill buffer

socket.Send(buffer, 3 + _body.Length + 1, SocketFlags.None);

答案 2 :(得分:1)

这取决于方法,如果你想用它来将数据写入套接字,它是可能的:

[DllImport("ws2_32.dll", SetLastError=true)]
static extern unsafe int send(IntPtr socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags);
//...
send(socket.Handle, buffer, 3 + _body.Length + 1, SocketFlags.None);

但是这种方法缺少很多控制检查和日志记录等,所以你真的应该使用已在这里发布的托管备选方案。