将字节指针传递给 CLR 函数

本文关键字:CLR 函数 字节 指针 | 更新日期: 2023-09-27 18:34:25

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

byte *buffer = stackalloc byte[256];
// fill buffer
socket.Send(buffer, 3 + _body.Length + 1, SocketFlags.None);

但是Visual Studio吐出了这个信息:

错误 27 参数 1:无法从"字节*"转换为"字节[]"

有没有办法在不分配新数组的情况下将指针转换为数组

将字节指针传递给 CLR 函数

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

如果需要托管阵列,则必须分配托管阵列,这是无法解决的。

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

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

byte[] buffer = new byte[256];
// fill buffer
socket.Send(buffer, 3 + _body.Length + 1, SocketFlags.None);
<</div> div class="answers">

这取决于方法,如果要使用它将数据写入套接字,则可以:

[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);

但是这种方法缺少许多控制检查和日志记录等,因此您实际上应该使用此处已经发布的托管替代方案。