我有一个C++ .NET应用程序和一个C#.NET应用程序.我希望他们通过共享内存进行通信.
.NET版本2.0怎么可能?
主要是想共享一个队列对象.
更新:嘿,这是我刚刚发现的一个页面,带有完整的实现.
使用C++/CLI,按照普通的C++ API(C++/CLI能够与托管和本机HEAP /内存引用交互)设置共享内存非常容易.然后可以使用UnmanagedMemoryStream将Stream对象公开给C#.
我没有附加.h文件,但你可以相当容易地推断出pmapped native typedef的布局;).您可能还想根据读者/编写器用例评估BufferedStream的可能用途.代码来自一个我不再使用的项目,所以我不记得它的bug回归的状态.
这是C++/CLI类,它建立文件映射并公开UnmanagedMemoryStream;
public ref class MemMapp { public: __clrcall MemMapp(String^ file) { map = NULL; if(!File::Exists(file)) throw gcnew ApplicationException("Can not find file " + file); marshal_context^ x = gcnew marshal_context(); const char *nname = x->marshal_as(file); map = (pmapped) malloc(sizeof(mapped)); ZeroMemory(map, sizeof(mapped)); map->name = strdup(nname); InitMap(map); } void __clrcall MapBytes(long long loc, long length) { map->low = loc & 0xffffffff; map->high = (loc >> 32) & 0xffffffff; map->size = length & 0xffffffff; if(!GetMapForFile(map)) throw gcnew ApplicationException("can not map range " + loc + " :" + length); if(map->size = 0) map->size = MAXMAX&0xffffffff; } UnmanagedMemoryStream ^View() { return gcnew UnmanagedMemoryStream((unsigned char *) map->blok, map->size, map->size, FileAccess::Read); } long long __clrcall FileSize() { DWORD high, low; long long rv; low = GetFileSize(map->hFile, &high); maxmax = high; maxmax << 32; maxmax += low; rv = high; rv << 32; rv = rv & low; return rv; } property unsigned int MinBufSiz { unsigned int get() { return map->dwbufz; } } property long long BufBase { long long get() { return (map->high << 32) + map->low; } } property long long BufLim { long long get() { return ((map->high << 32) + map->low) + map->size; } } property long long MAXMAX { long long get() { return maxmax; } } static MemMapp() { } __clrcall ~MemMapp() { if(map != NULL) { CloseMap(map); free(map->name); free(map); map = NULL; } } protected: __clrcall !MemMapp() { if(map != NULL) { CloseMap(map); free(map->name); free(map); map = NULL; } } pmapped map; long long maxmax; };
这里至少是CLoseMap ...我刚发现它...它没有用/ CLR编译
bool CloseMap(pmapped map) { if(map->blok != NULL) { UnmapViewOfFile(map->blok); map->blok = NULL; } if(map->hMap != INVALID_HANDLE_VALUE && map->hMap != NULL) { CloseHandle(map->hMap); map->hMap = INVALID_HANDLE_VALUE; } if(map->hFile != INVALID_HANDLE_VALUE && map->hFile != NULL) { CloseHandle(map->hFile); map->hFile = INVALID_HANDLE_VALUE; } return false; }
您的应用程序有多种选择可以进行通信.最受欢迎的是Remoting和Pipes.有两个例子,在您选择之前,您应该考虑优点和缺点,如可移植性.以下是一些有用的链接:
使用命名管道的.NET中的进程间通信,第1部分
使用命名管道的.NET中的进程间通信,第2部分
.NET Remoting简单英语
.NET Remoting有一个简单的例子