У меня есть приложение, которое может использовать плагины, которые загружаются во время выполнения с использованием 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
. Поскольку я просто хочу получить доступ к единой простой структуре, мне было интересно, как я могу помешать компоновщику выполнять большую часть своей работы.