1

I am trying to create .so file of a c++ file(twocams.cpp) which includes main() and another C++ file (say abc.h). abc.c includes opencv. while creating an object using ctypes,

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

i am getting error as:- undefined symbol: _ZN2cv12VideoCapturersERNS_3MatE

How to solve this problem? I want to use the c++ code in python. Any alternative is acceptable.

2 Answers2

0

When you create a shared object and want to use it, you have to link your artifact against all dependencies of this shared object. E.g. I create a libtwocams.so of

#include <opencv2/videoio.hpp>

void test() {
    cv::VideoCapture v;
    cv::Mat m;
    v >> m;
}

To use this shared object I have to link against libopencv_core, libopencv_videoio, libopencv_imgproc, libopencv_imgcodecs, libz and some more. I compile my program with

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

Another solution is to link the shared object against the dependent libraries. E.g.

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

creates a shared library that makes the loader load all dependencies. You can check the dependencies with ldd.

The order of the libraries is important. If libA has a dependency to libB then you have to link against libA and then libB.

If you use opencv's shared library then you don't need to link all other dependencies.

Here is a step by step manual:

Install conan

Install cmake

Add repository bincrafters to conan

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

Create:

  • conanfile.txt
  • CMakeLists.txt
  • src/twocams.cpp
  • build/

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})

Go to build and install dependencies:

cd build
conan install .. --build missing

Build project with cmake:

cmake ..
cmake --build .
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • Thanks @thomas, but the problem is i know how to use .so file and create shared object from it(to use it with other language like pyhton) but i do not know how to use shared library. It will be better if you can tell me how to create a .so file. – Arun Sharma Oct 31 '18 at 05:07
  • I also get an error ' cannot find -lwebp' while running the commands you suggested. Can you tell what needs to be done? – Arun Sharma Oct 31 '18 at 05:37
  • If your linker can't find libwebp you have to install it. How did you install opencv? Do link static or dynamic against opencv? – Thomas Sablik Oct 31 '18 at 07:14
  • I appreciate your help. Can you tell if i can use the shared library as .so file or it is different? I actually need a .so file to create a python object. – Arun Sharma Oct 31 '18 at 10:23
  • A .so file is a shared library aka shared object – Thomas Sablik Oct 31 '18 at 10:45
0

I had a similar issue, giving me an

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

in python, when calling

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

To resolve this, I did the following:

  1. In the cpp files, I replaced the general import #include <opencv2/opencv.hpp> by the specific ones: #include <opencv2/core/core.hpp> and #include <opencv2/imgproc/imgproc.hpp>
  2. Instead of giving the bash-output of pkg-config --libs --cflags opencv as arguments of the compilation command (which gave quite a list), I just used the specific flags: g++ -fPIC -shared -I/usr/include/opencv4 -lopencv_imgproc -lopencv_core -Wall -Wl,-soname,opencv_cust.so -o opencv_cust.so opencv_cust.cpp
Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58