0

我正在尝试创建一个 .NET Core 应用程序,但在 IPC 上有点卡住了。

我有数据通过可执行文件 1 进入(比如说,来自套接字或文件,某种流接口)。现在,我希望可执行文件 2 读取这些数据。所以,我创建了一个 MMF,其中可执行文件 1 写入数据,可执行文件 2 读取数据。一切都很好。

但是,我真的很想跳过这里的“复制”步骤。如果我有通过套接字传入的消息,我需要读取消息(ergo;将其存储在某个字节数组中),然后将其复制到适当的内存映射文件中。

有没有办法让他们使用相同的内存(尤其是现在,有了新的内存、跨度等)?

这段代码似乎几乎可以工作,但并不完全:

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年开始的。

4

0 回答 0