[英]Marshal a Memory<byte> to a native function expecting byte[]
我正在嘗試用 c# 包裝 OpenSSL 的 BIO 部分。 我試圖將 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 讀取的數據復制到內存中,而是希望將Memory<bytes>
的“字節數組”直接提供給BIO.read(..)
。 另外,我想通過writer.GetMemory()
來利用MemoryPool<byte>
而不是創建新的Memory<bytes>
s。
我並不像我希望的那樣擅長互操作,而且我在谷歌上找不到任何有用的東西。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.