dmc*_*kee 50

  • 如果您控制其中一个或两个:编辑一个以更改名称并重新编译或等效地查看Benunknown的答案,这些答案将无法访问源代码.
  • 如果你不控制其中任何一个,你可以将其中一个包起来.这是编译另一个(静态链接!)库,除了重新导出原始符号之外什么都不做,除了有问题的符号,这是通过带有备用名称的包装器到达的.多么麻烦.
  • 后来补充说:既然qeek说他正在谈论动态库,那么Ferrucciomouviciel提出的解决方案可能是最好的.(我似乎很久以前就生活过静态链接是默认的.它为我的想法着色.)

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

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

Ben*_*Ben 50

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

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

  • 不要忘记重命名头文件中的符号. (8认同)
  • 好的。这对于添加到 Makefile 来说是微不足道的。如果库被更新,objcopy 咒语将比其他一些解决方案更容易更新。 (2认同)

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


Jee*_*lee 9

如果那里有 .o 文件,这里有一个很好的答案:https : //stackoverflow.com/a/6940389/4705766

概括:

  1. objcopy --prefix-symbols=pre_string test.o 重命名 .o 文件中的符号

或者

  1. objcopy --redefine-sym old_str=new_str test.o 重命名 .o 文件中的特定符号。


Sni*_*gus 8

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

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

  • 重命名的机会是有限的,因为您只能使名称_更短_。同样在 Linux 上,您将很难更新 ELF 哈希表。 (3认同)

Vat*_*ine 7

发誓?据我所知,如果您有两个公开具有相同名称的链接点的库并且您需要链接这两个库,那么您无能为力。

  • 发誓*绝对*是第一步。毫无疑问。 (17认同)

vra*_*raa 7

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


mou*_*iel 6

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

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