.NET Core アプリケーションを作成しようとしていますが、IPC で少しスタックしています。
実行可能ファイル 1 を介して (たとえば、ソケット、またはファイル、ある種のストリーミング インターフェイスから) データが入ってきます。このデータを実行可能ファイル 2 で読み取れるようにします。つまり、MMF を作成しました。ここで、実行可能ファイル 1 はデータを書き込み、実行可能ファイル 2 はデータを読み取ります。すべては順調です。
ただし、ここでは「コピー」の手順をスキップしたいと思います。ソケット経由でメッセージを受信した場合は、そのメッセージを読み取り (つまり、何らかのバイト配列に格納する)、適切なメモリ マップ ファイルにコピーする必要があります。
それらに同じメモリを使用させる方法はありますか (特に現在、新しいメモリ、スパンなどを使用) はありますか?
このコードはほとんど動作しているように見えますが、完全ではありません:
const int bufferSize = 1024;
var mappedFile = MemoryMappedFile.CreateNew("IPCFile", bufferSize);
var fileAccessor = mappedFile.CreateViewAccessor(0, bufferSize, MemoryMappedFileAccess.ReadWrite);
// THere now exists a region of byte[] * bufferSize somewhere. I want to write to that.
byte[] bufferMem = new byte[bufferSize];
// I know the memory address where this area is, and I know the size of it:
unsafe
{
byte* startOfRegion = (byte*)0;
fileAccessor.SafeMemoryMappedViewHandle.AcquirePointer(ref startOfRegion);
// But how do I "assign" this region to the managed object?
// This throws "System.MissingMethodException: 'No parameterless constructor defined for type 'System.Byte[]'."
//bufferMem = Marshal.PtrToStructure<byte[]>(new IntPtr(startOfRegion));
// This almost looks like it works, but bufferMem remains null. Does not give any errors though.
bufferMem = Unsafe.AsRef<byte[]>(startOfRegion);
}
// For a shorter example, just using a file stream
var incomingData = File.OpenRead(@"C:\Temp\plaatje.png");
// Pass in the "reserved" memory region. But StreamPipeReaderOptions wants a MemoryPool<byte>, not a byte[].
// How would I cast that? MemoryPool is abstract, so can't even be instantiated
var reader = PipeReader.Create(incomingData, new StreamPipeReaderOptions(bufferMem));
ReadResult readResult;
// Actually read data
while (true)
{
readResult = await reader.ReadAsync();
if (readResult.IsCompleted || readResult.IsCanceled)
break;
reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
}
// Now signal the other process to read the contents of the MMF and continue
この質問は同様のことを尋ねているようですが、答えがなく、2013年のものです。