dmc*_*kee 50
评论:通过"导出"我的意思是使链接到库的模块可见 - 相当于extern文件范围的关键字.如何控制它取决于操作系统和链接器.这是我一直要抬头看的东西.
Ben*_*Ben 50
可以使用objcopy --redefine-sym old=new file(参见man objcopy)重命名目标文件中的符号.
然后只需使用新名称调用函数并链接到新的目标文件.
Fer*_*cio 14
在Windows下,您可以使用LoadLibrary()将其中一个库加载到内存中,然后使用GetProcAddress()获取需要调用的每个函数的地址,并通过函数指针调用函数.
例如
HMODULE lib = LoadLibrary("foo.dll");
void *p = GetProcAddress(lib, "bar");
// cast p to the approriate function pointer type (fp) and call it
(*fp)(arg1, arg2...);
FreeLibrary(lib);
Run Code Online (Sandbox Code Playgroud)
将获取foo.dll中名为bar的函数的地址并调用它.
我知道Unix系统支持类似的功能,但我想不出他们的名字.
如果那里有 .o 文件,这里有一个很好的答案:https : //stackoverflow.com/a/6940389/4705766
概括:
objcopy --prefix-symbols=pre_string test.o 重命名 .o 文件中的符号 或者
objcopy --redefine-sym old_str=new_str test.o 重命名 .o 文件中的特定符号。这是一个想法.在十六进制编辑器中打开其中一个违规库,并将所有出现的违规字符串更改为其他内容.然后,您应该能够在将来的所有呼叫中使用新名称.
更新: 我刚刚在这方面做了它似乎工作. 当然,我没有彻底测试过这个问题 - 这可能只不过是用一把霰弹枪吹掉你腿的好方法.
假设你使用linux,首先需要添加
#include <dlfcn.h>
Run Code Online (Sandbox Code Playgroud)
在适当的上下文中声明函数指针变量,例如,
int (*alternative_server_init)(int, char **, char **);
Run Code Online (Sandbox Code Playgroud)
就像Ferruccio在/sf/answers/47491741/中所述,通过执行明确加载要使用的库(选择你最喜欢的标志)
void* dlhandle;
void* sym;
dlhandle = dlopen("/home/jdoe/src/libwhatnot.so.10", RTLD_NOW|RTLD_LOCAL);
Run Code Online (Sandbox Code Playgroud)
请稍后读取要调用的函数的地址
sym = dlsym(dlhandle, "conflicting_server_init");
Run Code Online (Sandbox Code Playgroud)
分配和转换如下
alternative_server_init = (int (*)(int, char**, char**))sym;
Run Code Online (Sandbox Code Playgroud)
以与原始方式类似的方式呼叫.最后,通过执行卸载
dlclose(dlhandle);
Run Code Online (Sandbox Code Playgroud)
你不应该一起使用它们.如果我没记错的话,链接器会在这种情况下发出错误.
我没有尝试,但可以使用解决方案dlopen(),dlsym()并dlclose()允许您以编程方式处理动态库.如果您不需要同时使用这两个函数,则可以在使用第二个库/函数之前打开第一个库,使用第一个函数并关闭第一个库.