当前位置:  开发笔记 > 运维 > 正文

如果两个库提供具有相同名称的函数产生冲突,我该怎么办?

如何解决《如果两个库提供具有相同名称的函数产生冲突,我该怎么办?》经验,为你挑选了6个好方法。

如果我有两个提供相同名称功能的库,我该怎么办?



1> dmckee..:

如果您控制其中一个或两个:编辑一个以更改名称并重新编译或等效地查看Ben和unknown的答案,这些答案将无法访问源代码.

如果你不控制其中任何一个,你可以将其中一个包起来.这是编译另一个(静态链接!)库,除了重新导出原始符号之外什么都不做,除了有问题的符号,这是通过带有备用名称的包装器到达的.多么麻烦.

后来补充说:既然qeek说他正在谈论动态库,那么Ferruccio和mouviciel提出的解决方案可能是最好的.(我似乎很久以前就生活过静态链接是默认的.它为我的想法着色.)

评论:通过"导出"我的意思是使链接到库的模块可见 - 相当于extern文件范围的关键字.如何控制它取决于操作系统和链接器.这是我一直要抬头看的东西.


也许有人可以提供这种技术的简单例子?一个exe,两个库,每个库包含一个具有相同名称的函数.

2> Ben..:

可以使用objcopy --redefine-sym old=new file(参见man objcopy)重命名目标文件中的符号.

然后只需使用新名称调用函数并链接到新的目标文件.


不要忘记重命名头文件中的符号.

3> Ferruccio..:

在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系统支持类似的功能,但我想不出他们的名字.



4> Sniggerfardi..:

这是一个想法.在十六进制编辑器中打开其中一个违规库,并将所有出现的违规字符串更改为其他内容.然后,您应该能够在将来的所有呼叫中使用新名称.

更新: 我刚刚在这方面做了它似乎工作. 当然,我没有彻底测试过这个问题 - 这可能只不过是用一把霰弹枪吹掉你腿的好方法.



5> vraa..:

假设你使用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);



6> mouviciel..:

你不应该一起使用它们.如果我没记错的话,链接器会在这种情况下发出错误.

我没有尝试,但可以使用解决方案dlopen(),dlsym()dlclose()允许您以编程方式处理动态库.如果您不需要同时使用这两个函数,则可以在使用第二个库/函数之前打开第一个库,使用第一个函数并关闭第一个库.

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有