Я разработал несколько dll некоторое время назад, чтобы P / Invoke некоторые вещи от C ++ DLL до C #. Однако я работаю в жестких условиях реального времени, и P / Invoke оказался слишком медленным для выполнения определенных операций.
Поэтому я наткнулся на Memory Mapping как (предположительно) более быструю альтернативу P / Invoke, и во время моих тестов сторона C ++ не выглядела слишком потрепанной:
#include "stdafx.h"
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
char* pcTest = "Message from C++";
int _tmain()
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
BUF_SIZE,
szName);
if (hMapFile == NULL) {
_tprintf(TEXT("Could not create file mapping object (%d).\n"), GetLastError());
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(
hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
BUF_SIZE);
if (pBuf == NULL) {
_tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError());
CloseHandle(hMapFile);
return 1;
}
CopyMemory((PVOID)pBuf, pcTest, (strlen(pcTest) * sizeof(char*)));
std::cin.get();
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0;
}
Я адаптировал код отсюда:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
А вот сторона C #:
static void Main(string[] args)
{
MemoryMappedFile pagedMemoryMap = MemoryMappedFile.OpenExisting("MyFileMappingObject", MemoryMappedFileRights.FullControl);
using (MemoryMappedViewAccessor fileMap = pagedMemoryMap.CreateViewAccessor())
{
var array = new byte[256];
fileMap.ReadArray(0, array, 0, 16); //Take notice on this line
var text = Encoding.ASCII.GetString(array);
Console.WriteLine(text);
}
Console.ReadKey();
}
Он работает как задумано, но здесь есть проблема: этот фиксированный размер длины байтового массива в методе ReadArray. Я предполагаю, что мне придется записать длину фактических строк в моем реальном приложении в другой общий ресурс, а затем использовать его для чтения значения строки, но это кажется слишком громоздким. Учитывая, что то, что я на самом деле читаю из C ++ в реальном приложении, это массивы структур (которые в основном содержат только строки), получу ли я какое-либо преимущество от отображения памяти с точки зрения производительности? У меня нет никаких намерений вздувать стабильный код (хотя и медленно) с альтернативой, которая может не дать ожидаемых результатов, так есть ли какие-то реальные преимущества этого подхода? Есть ли лучшая альтернатива?
Отображенные в память файлы хороши для обмена данными между процессами. Они бессмысленны для совместного использования между модулями в одном и том же пространстве памяти.
Просто определите свою структуру данных как тип ссылочного класса обычным способом, а затем закрепите ее. Теперь C ++ может напрямую обращаться к структуре данных, используя обычный доступ с указателем.
Подсчитанные строки будут работать так же хорошо в закрепленных массивах, как и в отображенных в память файлах, за исключением того, что вам не понадобятся вызовы ядра для их настройки.
Других решений пока нет …