私はLinux(Ubuntu 12.04、gcc 4.6.3)を使用しており、必要に応じてプラグインをリロードできるプラグインベースのアプリケーションを作成するために、自分の意志に合わせてdlopen / closeを曲げようとしています(たとえば、再コンパイルされた場合) .
基本的な理論は単純です。プラグインを dlopen します。それを使用し、使用中のすべてのシンボルを追跡します。リロードするときが来たら、すべてのシンボルをクリーンアップし、プラグインを dlclose します。
簡単なデモ アプリ「test.cpp」をまとめました。
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argc > 1)
{
void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
if (!h)
{
cerr << "ERROR: " << dlerror() << endl;
return 1;
}
cin.get();
if (dlclose(h))
{
cerr << "ERROR: " << dlerror() << endl;
return 2;
}
cin.get();
}
return 0;
}
コンパイル:
g++ test.cpp -o test -ldl
上記のコードに引数として渡すことができる単純なライブラリを作成するには、次を使用します。
touch libtest.cpp && g++ -rdynamic -shared libtest.cpp -o libtest.so
次に、次のように実行します。
./test ./libtest.so
ここに問題があります。[Enter] を 1 回押した後 (つまり、ライブラリをロードしておそらくアンロードした後)、'pmap' を実行して 'test' にロードされているライブラリを確認すると、libtest.so がまだそこにあることがわかります! 現在、これは dlclose() からの有効な戻りにもかかわらず、参照カウントがそれより前に 1 を超えていた合理的な方法はありません (これは 2 番目の dlclose() を試行することで確認できます。閉まっている)。
したがって、Linuxが dlopen() されたライブラリをアンロードしない(ドキュメントと矛盾する) か、「pmap」が間違っています。後者の場合、ライブラリがまだロードされているかどうかを判断するより信頼できる方法はありますか?