gpt4 book ai didi

c++ - 在不修改源代码的情况下隐藏动态库中的符号

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:27 24 4
gpt4 key购买 nike

我有一个需要链接的闭源第 3 方共享库。不幸的是,第 3 方库的创建者并没有费心去限制导出哪些符号并导出所有符号。第 3 方库在内部使用我在代码中使用的流行库的不兼容版本,但导出冲突的符号(谷歌的 protobuf 库)。当 protobuffer 库版本检查发现库的编译时和运行时版本不兼容时,这会导致运行时错误。我可以通过恢复到与第 3 方库中使用的版本相匹配的旧版本的 protobufs 2.3 来解决问题。但是,protbuf 2.3 存在性能问题,导致我的应用程序无法使用。我需要一种在我的代码中使用 protobuf 2.4 并让第 3 方库使用它自己的内部 v 2.3 的方法。

有没有一种方法可以生成新版本的第 3 方库,它不会从内部使用的 protobuf v 2.3 库中导出符号,只给出 so 文件?如果我有来源,这将是一个更容易的问题。貌似objcopy、strip之类的工具不能真正修改动态符号表。到目前为止,我唯一的想法是创建我自己的垫片库,通过将调用重定向到第 3 方库(也许用 dlopen 打开?)来仅导出我需要的符号。

有没有更好的解决方案?

最佳答案

我找到了一个可行的解决方案...我创建了一个垫片库,它将调用重定向到第三方库,允许库外的代码看到 protbuf v2.4 符号,而第三方库内的代码看到 protobuf v2。 3个符号。此解决方法基于此处发布的想法:http://www.linuxjournal.com/article/7795

我必须修改 dlopen 标志以包含 RTLD_LAZY | RTLD_本地 | RTLD_DEEPBIND。 RTLD_LOCAL 标志使第三方库内部的符号不被填充库外部看到(防止符号泄漏)。 RTLD_DEEPBIND 强制从第 3 方库内部调用以仅查看符号的内部版本(防止符号泄漏)。

具体来说,这是从我的 shim 库中摘录的示例。

#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "libhdfs/hdfs.h"

//#define PRINT_DEBUG_STUFF

// Helper function to retrieve a function pointer to a function from libMapRClient
// while isolating the symbols used internally from those already linked externaly
// to workaround symbol collision problem with the current version of libMapRClient.
void* GetFunc(const char* name){
#ifdef PRINT_DEBUG_STUFF
printf("redirecting %s\n", name);
#endif
void *handle;
char *error;

handle = dlopen("/opt/mapr/lib/libMapRClient.so", RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);

if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
void* fp = dlsym(handle, name);
if ((error = dlerror()) != 0) {
fprintf(stderr, "%s\n", error);
exit(1);
}
return fp;
}


hdfsFS hdfsConnect(const char* host, tPort port) {
typedef hdfsFS (*FP) (const char* host, tPort port);
static FP ext = 0;
if (!ext) {
ext = (FP)GetFunc("hdfsConnect");
}
return ext(host, port);
}


int hdfsCloseFile(hdfsFS fs, hdfsFile file) {
typedef int (*FP) (hdfsFS fs, hdfsFile file);
static FP ext = 0;
if (!ext) {
ext = (FP)GetFunc("hdfsCloseFile");
}
return ext(fs, file);
}

... 其他公共(public) API 函数等等

关于c++ - 在不修改源代码的情况下隐藏动态库中的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10215250/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com