dlopenを使用して実行時にロードされるプラグインを利用できるアプリケーションがあります。各プラグインは、共通の構造を使用して定義されたプラグイン情報を取得する関数を定義します。そんな感じ:
struct plugin {
char *name;
char *app_version;
int app_verion_id;
char *plugin_version;
int plugin_version_id;
/* ... */
};
struct plugin p = { "sample plugin",APP_VERION,APP_VERSION_ID,"1.2.3",10203 };
struct plugin *get_plugin() {
return &p;
}
これはうまく機能し、プラグインをロードできます。ここで、アプリケーション全体をリンクせずにこれらのプロパティを読み取るための小さなツールを作成したいと思います。それを行うために、私はこのようないくつかのコードを持っています:
void *handle;
struct plugin *plugin;
struct plugin *(get_plugin*)();
handle = dlopen(filename, RTLD_LAZY);
if (!handle) { /*...return; ...*/ }
get_plugin = dlym(handle, "get_plugin");
if (!get_plugin) { /*...return; ...*/ }
plugin = get_plugin();
printf("Plugin: %s\n", plugin->name);
これは、単純なプラグインに適しています。問題は、多くのプラグインがアプリケーションからさらにシンボルを参照していることです。これらのシンボルは、RTLD_LAZYが設定されていても解決されます。(プラグイングローバルのものを初期化するために使用されるアプリケーションからのグローバル変数のように)したがって、dlopen()呼び出しは。のようなエラーで失敗しますfatal: relocation error: file sample_plugin.so: symbol application_some_symbol: referenced symbol not found
。単一の単純な構造にアクセスしたいだけなので、リンカーが彼の作業の多くを実行するのをどのように防ぐことができるのか疑問に思いました。