减少第三方库的导出符号

Al *_*Wld 2 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;
}
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

正在png_destroy_write_struct被 呼叫cv::imwrite

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

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

Emp*_*ian 5

我认为这就是问题所在?

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

我不想让 openCV 看到 libabc.so 导出的任何内容...我该怎么做?

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

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

这可以通过 来完成dlopen("liabc.so.", RTLD_LOCAL),甚至可能不起作用(具体取决于libabc.so链接方式)——它可能会导致libabc.so绑定到您的 版本libpng,并崩溃。

在 Linux 上,您还可以使用dlmopen(LM_ID_NEWLM, "libabc.so", ...)它将与代码的其余部分完全隔离,并且如果链接到包含其所有依赖项(或者您可以显式地将它们带入新的加载程序命名空间),则可能会起作用。libabc.solibabc.so

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