Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C dlopen/dlsym,尽可能少的链接_C_Dynamic_Linker_Dlopen - Fatal编程技术网

C dlopen/dlsym,尽可能少的链接

C dlopen/dlsym,尽可能少的链接,c,dynamic,linker,dlopen,C,Dynamic,Linker,Dlopen,我有一个应用程序,它可以利用运行时使用dlopen加载的插件。每个插件都定义了一个函数来检索使用公共结构定义的插件信息。诸如此类: struct plugin { char *name; char *app_version; int app_verion_id; char *plugin_version; int plugin_version_id; /* ... */ }; struct plugin p = { "sample plugi

我有一个应用程序,它可以利用运行时使用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\u plugin.So:symbol application\u some\u symbol:referenced symbol not found
。因为我只想访问单一的简单结构,所以我想知道如何防止链接器做那么多工作。

如何使用
objdump
进行肮脏的黑客攻击:

~$ objdump -s -j .rodata plugin.so plugin.so: file format elf32-i386 Contents of section .rodata: 20000000 73616d70 6c652070 6c756769 6e00332e sample plugin.3. 20000010 322e3100 312e322e 3300 2.1.1.2.3. ~$objdump-s-j.rodata plugin.so plugin.so:文件格式elf32-i386 第节的内容。rodata: 20000000 73616d70 6c652070 6c756769 6e00332e示例插件。 20000010 322e3100 312E322 E 3300 2.1.1.2.3。
根据
man dlopen
(重点是我的)

懒惰的

执行延迟绑定。
仅将符号解析为 引用它们,然后执行。如果 符号永远不会被引用,那么它 这个问题永远无法解决(不支持延迟绑定) 仅针对功能执行 引用;对变量的引用 当 已加载库。)


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

如果您使用的是elf二进制文件,您可能需要查看您的平台是否有可用的libelf。
有关更多信息,请尝试
manelf
。这可能会得到你所需要的,而不必实际链接。但我从未使用过它,所以我不知道。

构建插件时使用什么链接选项?是的,我希望有人能想出解决办法:-/谢谢,基于Solaris的gelf(3ELF)手册页中的一个示例,我创建了一个小工具,它可以动态生成一个。因此,使用所有需要的符号,然后加载这个。然后加载dlopen()这是我的插件。有点黑客,但可以工作:-)(可能我也可以用shell脚本来削减ldd输出…但现在可以工作,我可以在这里组织我的插件)好吧,你可能比我更聪明,制作了这个工具。非常有趣。很高兴我能帮上忙。