For some time , We hope to be able to python Call in c++ Code , Maybe it's for speed , Maybe it's to call an existing c++ Code .
There are also many related tutorials on the Internet , But their c++ The code is just a function or a class , The situation is relatively simple .
I found a good one c++ project , But I can't use python rewrite , So I will c++ Medium main Function as a class , And want to export it as a shared link library (.so file ), stay python Call in .
My difficulty is the class I want to export , Third party libraries are used OpenCV, And this class also uses other classes , The situation is complicated .
In fact, this is also true , If I just want to call c++ Implement a function or a simple class , Why not use it directly python How about writing ? The actual situation is just like what I said above , The complicated .
Be careful :opencv.cpp It is a class written by the author himself ( Be similar to RPPG.cpp), and OpenCV It's a third party library , Don't confuse
All three classes use OpenCV Third party Library , meanwhile HB Used RPPG Classes and opencv class ,RPPG Used opencv class , And I want to export HB class , Make it available in python Call in , Dependencies are complicated .
therefore , We use cmake To help compile so file
First of all we have Ubuntu20.04 Chinese compiler ( ( One )Ubuntu Install detailed tutorial ( From image making to NVIDIA The whole process of driver installation )—— Super detailed graphic tutorial )
Check to see if you have installed gcc:
If not installed :
# In the terminal , Execute sequentially
sudo apt-get update
sudo apt-get install build-essential gdb
Check to see if you have installed cmake:
If not installed , see also Kitware APT The repository For your platform
# .hpp The header file , Used to declare
# .cpp Implement the function or class declared in the header file
-project
--HB.cpp
--HB.hpp
--RPPG.cpp
--RPPG.hpp
--opencv.cpp
--opencv.hpp
--......
First of all, my structure directory is as follows , In section 2 The relationship between , Our aim is to derive HB.cpp by so file
We know that many parameters are specified at compile time ,CMakeLists.txt Just tell cmake Our compile time parameter settings .
We are project New under folder CMakeLists.txt file , The contents are as follows :
cmake_minimum_required(VERSION 3.0.0) # Minimum version
project(hbp VERSION 0.1.0) # Project name
set(CMAKE_CXX_FLAGS "-std=c++11") # add to c++11 standard
find_package(OpenCV REQUIRED) # add to OpenCV library
include_directories(${OpenCV_INCLUDE_DIRS})
add_library(opencv SHARED opencv.cpp) # hold opencv.cpp Export as link library ,SHARED Specify as shared link library
target_link_libraries(opencv ${OpenCV_LIBS}) # because opencv.cpp Used OpenCV, So will OpenCV link to opencv in , It is equivalent to telling opencv Where to find OpenCV
add_library(RPPG SHARED RPPG.cpp)
target_link_libraries(RPPG ${OpenCV_LIBS}) # RPPG Also used. OpenCV library , Also link
add_library(HB SHARED HB.cpp)
target_link_libraries(HB ${OpenCV_LIBS}) # HB Also used. OpenCV library
target_link_libraries(RPPG opencv) # RPPG Also used. opencv class
target_link_libraries(HB RPPG) # HB Used RPPG( meanwhile RPPG Links opencv, amount to HB Indirectly linked opencv)
It can be seen that :
stay project New China build Folder :
-project
--build/
--CMakeLists.txt
--HB.cpp
--HB.hpp
--RPPG.cpp
--RPPG.hpp
--opencv.cpp
--opencv.hpp
--......
Then enter... In the terminal build/, Carry out orders :$ cmake ..
:
Re execution :$ make
:
Then you get what you want HB.so
file :
( Will automatically add lib- Prefix , therefore libHB.so Is the compiled file )
Success at compile time does not mean true success , We need to check .
Carry out orders $ ldd -r libHB.so
:
It means success .
What is it like to fail ?
If I follow python call C++ The function in 【 The most concise tutorial 】 compile so file :$ g++ -o HB.so -shared -fPIC HB.cpp
obtain HB.so file , Now check if there is any problem with this $ ldd -r HB.so
:
You can see a lot of "undefined symbol:“, From the back _ZN2cv
8fastFreeEPv It can be seen that OpenCV Link to , Resulting in the use of OpenCV Function is "undefined symbol:”, Similarly, you can also see “RPPG” etc. .
If you want to see what the function is , You can carry out the order :c++filt _ZN2cv8fastFreeEPv
You can see which function the following string represents
Just give the code :
import ctypes
dll=ctypes.cdll.LoadLibrary
# load so Link library
lib=dll("./libHB.so")
# Here is the call HB Class load function
lib.load()
You can see C++ in HB.load() If the function is executed successfully, the string will be printed :
Check it out , function python Code ,ok!