c++ - 减少第三方库的导出符号

标签 c++ opencv shared-libraries dynamic-linking dynamic-loading

我的代码运行良好,但如果我将我的项目链接到第三方库 libabc.so(源不可用),然后我突然遇到段错误。

我有一个看起来像这样的主

#include <opencv2/imgcodecs.hpp>
#include "Abc.h"

int main(int argc, char **argv)
{
    Abc dummyAbc;
    auto img = cv::imread("dummy.png");
    cv::imwrite("123.png", img);
    return 0;
}

CMakeList.txt如下

cmake_minimum_required(VERSION 3.1)
set(CMAKE_C_STANDARD 11)
find_package(OpenCV COMPONENTS core highgui imgcodecs)
include_directories(${OpenCV_INCLUDE_DIR})

add_executable(my_project Main.cpp)
target_link_libraries(my_project ${OpenCV_LIBRARIES} abc)

这编译很好,但运行时出现段错误。如果我删除行

Abc dummyAbc;

然后一切正常(即没有丢失文件或 opencv 的问题)。

如果我检查段错误的堆栈,我会看到:

Thread 1 "my_project" received signal SIGSEGV, Segmentation fault.
0x00007fdea96836b3 in png_destroy_write_struct () from /usr/local/lib/libabc.so

png_destroy_write_structcv::imwrite 调用。

libpng.solibabc.so (!!) 导出 png_destroy_write_struct 它实际上导出了所有的 libpng API(我假设它被静态链接到?)。我假设这是问题所在?我不想让 openCV 看到任何 libabc.so 导出...我该怎么做?

我尝试使用 objcopy --prefix-symbols abc_ libabc.so 但不知何故它没有帮助,现在崩溃发生在 abc_png_destroy_write_struct

最佳答案

I assume this is the problem?

是的:这很可能:libabc.so 静态链接(可能是不同版本的)libpng,并引入了符号冲突。

I do no want openCV to see whatever libabc.so exports... How can I do this?

你不能。您必须联系 libabc.so 开发人员,并告诉他们隐藏 libpng 符号。

唯一的其他选择(对于单进程执行)是动态加载 libabc.so

这可以通过 dlopen("liabc.so.", RTLD_LOCAL) 完成,即使这样也可能行不通(具体取决于 libabc.so 的链接方式) -- 它可能会导致 libabc.so 绑定(bind)到您的 libpng 版本,然后崩溃。

在 Linux 上,您还可以使用 dlmopen(LM_ID_NEWLM, "libabc.so", ...) 这将完全隔离 libabc.so,如果 libabc.so 被链接以包含其所有依赖项(或者您可以将它们放入新的加载程序命名空间中),则可能工作明确地)。

最后,正如 Eljay 在这里评论的那样,您可以使用进程间通信并拥有完全独立的进程加载 libabc.so。这将比直接使用 libabc.so 性能差很多,但总比没有好。

关于c++ - 减少第三方库的导出符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59021856/

相关文章:

python - 相机标定opencv python鸟瞰视角变换

c++ - boost asio async_read 延迟(本地套接字)

删除时C++ valgrind内存丢失?

python - 如何获得高斯滤波器?

python - 如何使用NumPy提高像素数学速度

c++ - 使用共享库和不匹配的编译器

google-maps - 安卓 : requires unavailable shared library com. google.android.maps;失败

linux - 创建静态库时嵌入所有外部引用

c++ - 我可以使用迭代器访问优先级队列的元素吗?

c++ - 在 Qt、QtCreator 和 QMake 中配置 GCC 编译器开关