将Memory <byte>编组到本机函数中,该函数需要byte []

时间:2019-06-13 17:56:29

标签: c#

我正在尝试将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上找不到任何有帮助的东西。

1 个答案:

答案 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);