我有一个使用单例的程序。该程序在运行时加载共享库。该库也使用相同的单例。 问题是,当从库中访问单例时,会创建一个新的单例实例。
该程序与-rdynamic
相关联,我同时使用-fPIC
,加载如下:
std::shared_ptr<Module> createModuleObject(const std::string& filename)
{
if (!fs::exists(filename))
throw std::runtime_error("Library not found: " + std::string(filename));
struct export_vtable* imports;
void *handle = dlopen(filename.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (handle) {
imports = static_cast<export_vtable*>(dlsym(handle, "exports"));
if (imports)
return std::shared_ptr<Module>(imports->make());
else
throw std::runtime_error("Error trying to find exported function in library!");
} else
throw std::runtime_error("Error trying to load library: " + std::string(filename));
}
该库导出一个这样的类:
Module* make_instance()
{
return new HelloWorld();
}
struct export_vtable
{
Module* (*make)(void);
};
struct export_vtable exports = { make_instance };
并且该类使用单例。
这是单身人士的创建方式(Configuration.cpp
):
std::unique_ptr<Configuration> Configuration::instance_(nullptr);
std::once_flag Configuration::onlyOnceFlag_;
Configuration& Configuration::instance()
{
if (instance_ == nullptr)
{
std::cout << "INSTANCE IS NULL, CREATING NEW ONE" << std::endl;
std::call_once(Configuration::onlyOnceFlag_,
[] {
Configuration::instance_.reset(new Configuration());
});
}
return *Configuration::instance_;
}
程序和库都链接到Configuration.cpp
。如果我从库中省略它,我在尝试访问单例时会收到一个未定义的符号错误。
任何人都知道如何解决这个问题?非常感谢你!
答案 0 :(得分:0)
以下是我为https://github.com/kvahed/codeare/blob/master/src/core/ReconStrategy.hpp解决的问题
加载共享对象后,我将全局单例Workspace
的实例分配给dll中的已加载类。 https://github.com/kvahed/codeare/tree/master/src/modules中的所有类都派生自ReconStrategy
和共享对象。好的是这段代码是可移植的。
构建这样的ReconStrategy时会发生这种情况:
ReconContext::ReconContext (const char* name) {
m_dlib = LoadModule ((char*)name);
if (m_dlib) {
create_t* create = (create_t*) GetFunction (m_dlib, (char*)"create");
m_strategy = create();
m_strategy->Name (name);
m_strategy->WSpace (&Workspace::Instance());
} else {
m_strategy = 0;
}
}
}
这里的关键是m_strategy->WSpace (&Workspace::Instance());