我有一个在Windows下运行的简单项目。它由两个DLL和一个EXE组成。EXE加载两个DLL。每个类都将在由std :: unique_ptr全局性实例化的类中创建一个共享内存对象。只有在使用/ MTd开关(多线程调试)而不是/ MDd(多线程调试DLL)的情况下,崩溃才会在FreeLibrary中发生。
我使用以下方法构建了增强库:
b2.exe -a -j %NUMBER_OF_PROCESSORS% --prefix=%BOOST% --libdir=%BOOST%/lib/x86 --reconfigure --build-type=complete --toolset=msvc-14.2 link=static address-model=32 runtime-link=static runtime-link=shared threading=multi define=BOOST_USE_WINDOWS_H define=NOMINMAX install
%BOOST%
指向我的BOOST安装文件夹。
我希望有人可以帮助我,基督徒。
示例代码:
APOLLOSHM \ dllmain.cpp
#include <memory>
#include "../shared/SHMBASE.h"
std::unique_ptr<SHM> shm;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call, LPVOID )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
shm = std::make_unique<SHM>("a_shm");
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
PHONYXSHM \ dllmain.cpp
#include <memory>
#include "../shared/SHMBASE.h"
std::unique_ptr<SHM> shm;
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
shm = std::make_unique<SHM>("p_shm");
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
shared \ SHMBASE.h
#ifndef SHAREDMEM_H
#define SHAREDMEM_H
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
class SHMBASE
{
boost::interprocess::shared_memory_object shm;
boost::interprocess::mapped_region region;
protected:
void* addr{ nullptr };
public:
SHMBASE(const char* n)
{
try {
boost::interprocess::shared_memory_object::remove(n);
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_or_create,
n, boost::interprocess::read_write);
}
catch (boost::interprocess::interprocess_exception & ex) {
throw std::runtime_error(ex.what());
}
}
void create_shm(size_t size)
{
shm.truncate(size);
region = boost::interprocess::mapped_region(shm,
boost::interprocess::read_write);
addr = region.get_address();
}
};
struct shared_memory_info
{
char x[20];
int y;
};
class SHM : public SHMBASE
{
public:
SHM(const char* n) :
SHMBASE(n)
{
create_shm(sizeof(shared_memory_info));
shm = static_cast<shared_memory_info*>(addr);
}
shared_memory_info* shm;
};
#endif
SharedMemTest \ SharedMemTest.cpp
#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <Windows.h>
struct LIBOBJ
{
HMODULE libhandle{ nullptr };
LIBOBJ(std::string libname){
libhandle = LoadLibraryA(libname.c_str());
if (!libhandle) {
throw std::runtime_error("Cannot open library");
}
}
~LIBOBJ() {
if (libhandle){
FreeLibrary(libhandle);
}
}
};
int main(){
std::vector<std::string> dlls = {"ApolloSHM.dll", "PhonyxSHM.dll"};
std::vector<std::unique_ptr<LIBOBJ> > objs;
try{
for (auto& n : dlls){
objs.emplace_back(std::make_unique<LIBOBJ>(n));
}
// if freelibrary in reverse order no crash
// for (auto it = objs.rbegin(); it != objs.rend(); ++it)
// if in order of loading it crashes, but only with /MTd
// for (auto it = objs.begin(); it != objs.end(); ++it)
for (auto it = objs.begin(); it != objs.end(); ++it){
it->reset();
}
}
catch (std::exception & e){
std::cout << "Exception: " << e.what() << std::endl;
}
return 0;
}
我想我已经解决了这个问题(也许只是对我来说)。问题不在于编译器的/MTd
开关。我认为问题与boost::interprocess::shared_memory_object
中的单例实现有关。我的项目结构如下:
一个EXE文件加载一个DLL(驱动程序包装器),该DLL可以并行加载多个设备驱动程序DLL。如文档中所述,两个驱动程序DLL正在使用它们自己的shared_memory_object
,并且在两种情况下都可以工作。直到我为驱动程序DLL调用FreeLibrary。在那种情况下,第二个FreeLibrary总是崩溃(但不是/MDd
,我不明白这秒钟的事实,对不起)。
我通过在驱动程序包装DLL中创建boost::interprocess::shared_memory_object
解决了该问题。我只是实例化了这样一个对象,并在下一行中将其删除。如果执行此操作,我的DLL将不会再崩溃。
希望这对boost::interprocess
的开发人员有所帮助。
亲切的问候,基督教