简体   繁体   中英

Marshal a Memory<byte> to a native function expecting byte[]

I am trying to wrap the BIO portion of OpenSSL in c#. I am trying to expose BIOs as IDuplexPipes.

BIOs have a read(byte[] buffer, int length) function. As you can see, the BIO is expecting a byte[] but the PipeWriter provides only Memory<byte> .

The imported function looks like this:

[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int BIO_read(IntPtr b, byte[] buf, int len);

which is then wrapped like this in BIO class:

public int Read(byte[] buffer, int length)
{
    return SSL.BIO_read(Handle, buffer, length);
}

The pipe's code looks like this:

public async void DoReadAsync()
{
    var writer = _inputPipe.Writer;

    while(true)
    {
        Memory<byte> mem = writer.GetMemory(_sizeHint);

        _bio.Read(mem???, _sizeHint); <- here is my confusion.
        ...
    }
}

I'm hoping to avoid copying the data read from the BIO to the mem, and instead would like to provide the Memory<bytes> 's "byte array" directly to BIO.read(..) . Also, I would like to take advantage of the MemoryPool<byte> with writer.GetMemory() rather than creating new Memory<bytes> s.

I'm not as good at interop as I'd like to be, and I am not finding anything on google that helps.

Interop Services provides a means to get an ArraySegment which can be accessed as an array.

TryGetArray(ReadOnlyMemory, ArraySegment)

Tries to get an array segment from the underlying memory buffer. The return value indicates the success of the operation.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM