シングルトンを使用するプログラムがあります。このプログラムは、実行時に共有オブジェクトライブラリをロードします。このライブラリは同じシングルトンも使用します。 問題は、ライブラリからシングルトンにアクセスするときに、シングルトンの新しいインスタンスが作成されることです。ランタイム動的ロードとシングルトン
プログラムが-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
に対するライブラリリンクの両方。ライブラリから省略した場合、シングルトンにアクセスしようとすると、未定義のシンボルエラーが発生します。
誰でもこの問題を解決する方法がありますか?どうもありがとうございました!
です。動的リンクライブラリでは意図したとおりに動作しません。また、[Scott MeyerのSingleton Pattern](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern)に固執してください。 – user0042
シングルトンには何も問題ありません。この特定のインプリメンテーションには2つの問題があります。1)シングルトンのライフタイムを制御できない。最初にインスタンスメソッドを呼び出す際にシングルトンを作成することは決して良い考えではありません。 2)あなたのライブラリは、親アプリケーションによって作成されたシングルトンを要求するのではなく、独自のシングルトンを作成します。この 'instance()'メソッドを修正するには、メインアプリケーションからインポートする必要があります。 P.S. Scott MeyerのSingleton Patternは、Antipatternと呼ばれるべきです。 – VTT
ライブラリ内で同じシングルトンを再利用することは可能でしょうか?そうではありませんか?問題は、他のものを隠しているライブラリ内のシングルトンであるようです。 'setConfiguration()'メソッドなどをライブラリに持たせることは、私にとってはあまり意味がありません。 **編集:**「メインアプリケーションからインポートする」とはどういう意味ですか? – Pfaeff