У меня есть простой проект под Windows. Он состоит из двух DLL и одного EXE. EXE загружает две библиотеки DLL. Каждый из них создаст объект разделяемой памяти в классе, созданном глобализацией std :: unique_ptr. Cra sh происходит во время FreeLibrary, и только если я использую ключ / MTd (многопоточная отладка) вместо / MDd (многопоточная отладочная DLL).
Я собрал буст-библиотеки, используя:
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;
}