现在有一个DLL,这个DLL内部有一个C++对象将在多个使用该DLL的进程间共享。查了MSDN之后知道,为了在进程间共享DLL内部的C++对象,唯一的办法就是用Memory-Mapped Files。我的做法当然是在DLL的内部CreateFileMapping,然后MapViewOfFile,取出共享的内存,如果是第一个加载该DLL的进程,就初始化C++对象。当第二个进程再调用CreateFileMapping函数时,通过GetLastError函数就知道内存映像已经创建,直接取C++对象来用。但是:问题的关键就在于:第一次创建内存映像时,需要指定内存大小,我用的是C++类的大小,但是该C++对象内部有一个指针类型的成员变量,第一个加载DLL的进程会初始化该指针,这样就只能在第一个加载DLL的进程内部使用该C++对象了。当第二个进程加载DLL时,它试图取到那个C++对象,但是,因为指针的原因,会出现拒绝访问。请问:如何解决这个问题——如果我要在进程之间共享一个含有指针类型成员变量的C++对象,该怎么办?创建内存映像的代码如下:
g_HSchema = CreateFileMapping(
(HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
sizeof(g_Schema),
"mappedmemmoryforschema");
if(!g_HSchema)
{
DWORD errcode = GetLastError();
throw dll_error("在InitializeDll中创建内存文件映像出错!");
}
bool isFirstInit = (ERROR_ALREADY_EXISTS != GetLastError());
g_pSchema = MapViewOfFile(
g_HSchema,
FILE_MAP_WRITE,
0,
0,
0);
if(!g_pSchema)
{
DWORD errcode = GetLastError();
throw dll_error("取内存文件映像时出错!");
}
ISchemaPtr* MemoryMappedSchema = (ISchemaPtr*)g_pSchema;
if(isFirstInit) //如果是首次加载Schema文件到内存
{
IXMLDOMSchemaCollection2Ptr SchemaCollection;
HRESULT hr = SchemaCollection.CreateInstance(__uuidof(XMLSchemaCache40));
if(FAILED(hr))
throw dll_error("InitializeDll中CreateInstance失败!");
try
{
SchemaCollection->add("http://www.mapgis.cn", "sample.xsd");
}
catch(_com_error)
{
throw dll_error("DLL在加载Schema文件时出现致命错误!请检查Schema文件!");
}
*MemoryMappedSchema = SchemaCollection->getSchema("http://www.mapgis.cn"); //初始化内存映象
//上一步会初始化C++类里的那个指针类型的成员变量
}
g_Schema = *MemoryMappedSchema; //第一个进程到这里挺好,第二个进程到这里会出现拒绝访问。