1

我有一个应用程序可以使用在运行时使用 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. 因为我只想访问单个简单结构,所以我想知道如何阻止链接器完成他的大部分工作。

4

3 回答 3

1

如果您使用的是 elf 二进制文件,您可能想查看您的平台是否有可用的 libelf。尝试man elf了解更多信息。这可能会为您提供所需的东西,而无需实际链接。不过我没用过,所以不知道。

于 2010-04-12T20:27:09.477 回答
1

根据man dlopen(重点是我的)

RTLD_LAZY

执行惰性绑定。
仅在执行引用它们的代码时解析符号。如果符号从未被引用,则它永远不会被解析。 (惰性绑定只对函数引用执行;对变量的引用总是在加载库时立即绑定。)

因此,您需要将插件可能使用的所有全局变量添加到您的工具中。

于 2010-04-10T18:22:10.487 回答
0

一个肮脏的黑客怎么样objdump

~$ objdump -s -j .rodata plugin.so  

plugin.so:文件格式elf32-i386

.rodata 部分的内容:
 20000000 73616d70 6c652070 6c756769 6e00332e 示例 plugin.3。
 20000010 322e3100 312e322e 3300 2.1.1.2.3。      

于 2010-04-10T18:19:22.073 回答