如果我有两个提供相同名称功能的库,我该怎么办?
如果您控制其中一个或两个:编辑一个以更改名称并重新编译或等效地查看Ben和unknown的答案,这些答案将无法访问源代码.
如果你不控制其中任何一个,你可以将其中一个包起来.这是编译另一个(静态链接!)库,除了重新导出原始符号之外什么都不做,除了有问题的符号,这是通过带有备用名称的包装器到达的.多么麻烦.
后来补充说:既然qeek说他正在谈论动态库,那么Ferruccio和mouviciel提出的解决方案可能是最好的.(我似乎很久以前就生活过静态链接是默认的.它为我的想法着色.)
评论:通过"导出"我的意思是使链接到库的模块可见 - 相当于extern
文件范围的关键字.如何控制它取决于操作系统和链接器.这是我一直要抬头看的东西.
可以使用objcopy --redefine-sym old=new file
(参见man objcopy)重命名目标文件中的符号.
然后只需使用新名称调用函数并链接到新的目标文件.
在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);
将获取foo.dll中名为bar的函数的地址并调用它.
我知道Unix系统支持类似的功能,但我想不出他们的名字.
这是一个想法.在十六进制编辑器中打开其中一个违规库,并将所有出现的违规字符串更改为其他内容.然后,您应该能够在将来的所有呼叫中使用新名称.
更新: 我刚刚在这方面做了它似乎工作. 当然,我没有彻底测试过这个问题 - 这可能只不过是用一把霰弹枪吹掉你腿的好方法.
假设你使用linux,首先需要添加
#include
在适当的上下文中声明函数指针变量,例如,
int (*alternative_server_init)(int, char **, char **);
就像Ferruccio在/sf/ask/17360801/中所述,通过执行明确加载要使用的库(选择你最喜欢的标志)
void* dlhandle; void* sym; dlhandle = dlopen("/home/jdoe/src/libwhatnot.so.10", RTLD_NOW|RTLD_LOCAL);
请稍后读取要调用的函数的地址
sym = dlsym(dlhandle, "conflicting_server_init");
分配和转换如下
alternative_server_init = (int (*)(int, char**, char**))sym;
以与原始方式类似的方式呼叫.最后,通过执行卸载
dlclose(dlhandle);
你不应该一起使用它们.如果我没记错的话,链接器会在这种情况下发出错误.
我没有尝试,但可以使用解决方案dlopen()
,dlsym()
并dlclose()
允许您以编程方式处理动态库.如果您不需要同时使用这两个函数,则可以在使用第二个库/函数之前打开第一个库,使用第一个函数并关闭第一个库.