我正在尝试将OpenSSL的BIO部分包装在c#中。我正在尝试将BIO公开为IDuplexPipes。
BIO具有read(byte[] buffer, int length)
功能。如您所见,BIO期望byte[]
,但PipeWriter
仅提供Memory<byte>
。
导入的函数如下:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int BIO_read(IntPtr b, byte[] buf, int len);
然后将其像这样包装在BIO类中:
public int Read(byte[] buffer, int length)
{
return SSL.BIO_read(Handle, buffer, length);
}
管道的代码如下:
public async void DoReadAsync()
{
var writer = _inputPipe.Writer;
while(true)
{
Memory<byte> mem = writer.GetMemory(_sizeHint);
_bio.Read(mem???, _sizeHint); <- here is my confusion.
...
}
}
我希望避免将从BIO读取的数据复制到mem,而是希望将Memory<bytes>
的“字节数组”直接提供给BIO.read(..)
。另外,我想将MemoryPool<byte>
与writer.GetMemory()
结合使用,而不是创建新的Memory<bytes>
。
我不擅长互操作,而且我在Google上找不到任何有帮助的东西。
答案 0 :(得分:0)
Interop Services提供了一种获取ArraySegment的方法,该方法可以作为数组进行访问。
TryGetArray(ReadOnlyMemory,ArraySegment)
尝试从基础内存缓冲区中获取数组段。返回值指示操作成功。
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices?view=netcore-3.0
using System.Runtime.InteropServices;
//Turn memory space into ArraySegment for port use
if (!MemoryMarshal.TryGetArray(memory, out ArraySegment<byte> arraySegment))
{
throw new InvalidOperationException("Buffer backed by array was expected");
}
int bytesRead = port.Read(arraySegment.Array, 1000);