我有一個使用單身的程序。該程序在運行時加載共享對象庫。這個庫也使用同一個單例。 問題是,當從庫中訪問單例時,將創建單例的新實例。運行時動態加載和單身人士
程序與-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
庫鏈接。如果我從庫中省略,嘗試訪問單例時遇到未定義的符號錯誤。
任何人都知道如何解決這個問題?非常感謝你!
這就是爲什麼單身是一個壞主意的原因之一。它們不能像動態鏈接庫那樣按預期工作。還相當堅持[斯科特邁耶的Singleton模式](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern)。 – user0042
單身沒什麼問題。這個特定的實現有兩個問題:1)你放棄了對單身生命的控制。首次調用獲取實例方法創建單例從來都不是一個好主意。 2)你的庫創建它自己的單例,而不是請求由父應用程序創建的單例。爲了解決這個'instance()'方法應該從主應用程序導入。附:斯科特邁耶的單身模式應該被稱爲反模式。 – VTT
應該有可能重用庫中的同一個單例,但不是嗎?問題似乎是圖書館內部的單身人士隱瞞另一人。 有一個'setConfiguration()'方法或庫中的某些東西對我來說也不是一種選擇,因爲它有點違背了目的。 **編輯:**你是什麼意思的「從主應用程序導入」? – Pfaeff