运行时动态加载和单例

Runtime Dynamic Loading and Singletons

本文关键字:单例 加载 动态 运行时      更新时间:2023-10-16

我有一个使用单例的程序。该程序在运行时加载共享对象库。该库还利用同一单身人士。问题是,当从库中访问单例时,创建了一个新实例。

该程序与-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 };

,该课程利用了Singleton。

这就是创建单例的方式(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的程序和库链接均链接。如果我从库中省略了这一点,则在尝试访问Singleton时会收到一个未定义的符号错误。

有人想知道如何解决这个问题吗?非常感谢!

这是我为https://github.com/kvahed/codeare/blob/master/src/src/core/core/reconstrategy.hpp求解。加载共享对象后,我将Global Singleton Workspace的实例分配给DLL中的加载类。https://github.com/kvahed/codeare/tree/master/master/src/modules中的所有类均来自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());