在C++代码中包含opencv时,使用ctypes创建.so文件

Creating .so file using ctypes when opencv is included in C++ code

本文关键字:ctypes 使用 创建 so 文件 代码 C++ 包含 opencv      更新时间:2023-10-16

我正在尝试创建一个c++文件(twocams.cpp(的.so文件,该文件包括main((和另一个c++(比如abc.h(。abc.c包括opencv。使用ctypes、创建对象时

g++ -fPIC -shared twocams.cpp -o twocams.so
Test = ctypes.cdll.LoadLibrary('/home/administrator/Desktop/project/twocams/twocams.so')

我的错误是:-未定义符号:_ZN2cv12VideoCapturersERNS_3MatE

如何解决这个问题?我想在python中使用c++代码。任何替代方案都是可以接受的。

当您创建一个共享对象并想要使用它时,您必须根据该共享对象的所有依赖项链接您的工件。例如,我创建的libtwocams.so

#include <opencv2/videoio.hpp>
void test() {
cv::VideoCapture v;
cv::Mat m;
v >> m;
}

要使用这个共享对象,我必须链接到libopencv_core、libopencv_videio、libopenc_imgproc、libopenv_imgcodecs、libz等。我用编译我的程序

g++ main.cpp -o main -ltwocams -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio -lz -lwebp -lpthread -ltiff -lpng

另一种解决方案是将共享对象与依赖库链接起来。例如

g++ -fPIC -shared twocams.cpp -o -ltwocams -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio -lz -lwebp -lpthread -ltiff -lpng

创建一个共享库,使加载程序加载所有依赖项。您可以使用ldd检查依赖关系。

图书馆的秩序很重要。如果libA对libB有依赖关系,则必须先链接libA,然后链接libB。

如果使用opencv的共享库,则不需要链接所有其他依赖项。

以下是一份循序渐进的手册:

安装conan

安装cmake

将存储库bincrafter添加到conan

conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan

创建:

  • conanfile.txt
  • CMakeLists.txt
  • src/twocams.cpp
  • 构建/

conanfile.txt:

[requires]
opencv/3.4.2@bincrafters/stable
[generators]
cmake
[options]
opencv:shared=True

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)
project(twocams)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_library(twocams SHARED src/twocams.cpp src/twocams.h)
target_link_libraries(twocams ${CONAN_LIBS})

转到build并安装依赖项:

cd build
conan install .. --build missing

使用cmake:构建项目

cmake ..
cmake --build .

我遇到了类似的问题,给了我一个

OSError: /lib64/libarmadillo.so.9: undefined symbol: H5Ovisit

在python中,调用时

libCustCv = ctypes.cdll.LoadLibrary('./../so/opencv_cust.so')

为了解决这个问题,我做了以下操作:

  1. 在cpp文件中,我用特定的#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>替换了常规导入#include <opencv2/opencv.hpp>
  2. 我没有将pkg-config --libs --cflags opencv的bash输出作为编译命令的参数(这给出了一个相当多的列表(,而是使用了特定的标志:g++ -fPIC -shared -I/usr/include/opencv4 -lopencv_imgproc -lopencv_core -Wall -Wl,-soname,opencv_cust.so -o opencv_cust.so opencv_cust.cpp