参考:
- C++ 调用Python脚本
- C/C++调用python(新手必看)
- c调用python遇到的那些坑
- 解决PyRun_SimpleFile/PyRun_SimpleString报错
- “探坑”——在C++中执行python脚本的艰辛尝试
背景介绍:
做 deepsort 跟踪部署 c++ 调用 python 时出现好多错误,记录下来,方便后续排查。用的IDE 是clion,众所周知它生成的可执行文件在 ./cmake-build-debug 目录下,所以查找 python 文件的位置要相对于./cmake-build-debug下的可执行文件,而不是相对于源文件。
错误1:PyImport_ImportModule老返回NULL
tree-查看目录和文件
本例中 test.cpp 调用 ./Python 中的 main_test.py
$ tree -L 2
.
├── cmake-build-debug
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── Makefile
│ ├── test
│ └── test1.cbp
├── CMakeLists.txt
├── main.cpp
├── __pycache__
├── Python
│ ├── deep_sort
│ ├── detector.py
│ ├── __init__.py
│ ├── main_test.py
│ ├── models
│ ├── __pycache__
│ ├── run.py
│ ├── test_test.py
│ ├── tracker.py
│ ├── utils
│ ├── weights
│ └── yolov5
├── test.cpp
└── video
├── getvideo_189_2019-07-20_09-17-48.avi
└── test.mp4
CMakeLists.txt 为:
cmake_minimum_required(VERSION 3.10)
project(test1)
set(CMAKE_CXX_STANDARD 14)
set(OpenCV_DIR /home/wxf/softwares/3rdparty/opencv_env/opencv349/share/OpenCV)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(/home/wxf/softwares/3rdparty/anaconda/envs/deepsort_py37/include)
add_executable(test test.cpp)
target_link_libraries(test
${OpenCV_LIBS}
/home/wxf/softwares/3rdparty/anaconda/envs/deepsort_py37/lib/libpython3.7m.so)
add_executable(main main.cpp)
target_link_libraries(main
${OpenCV_LIBS}
/home/wxf/softwares/3rdparty/anaconda/envs/deepsort_py37/lib/libpython3.7m.so)
出现这个错误时:
受到启发:c++加载python模块,但是PyImport_ImportModule老返回NULL
PyRun_SimpleString改为:
PyRun_SimpleString("sys.path.append(r'../Python')");
并且删除 cmake-build-debug 文件夹,重新编译。
错误2: ModuleNotFoundError: No module named ‘tracker’
test.cpp 调用 ./Python 中的 main_test.py
main_test.py 导入 的包是:
import numpy as np
import cv2
import tracker
from detector import Detector
numpy 、opencv 是装的包
tracker 是 tracker.py ,detector 是 detector.py 自己写得包
参考: ModuleNotFoundError: No module named 'xxx’可能的解决方案大全
从 Python中import导入模块时出现ImportError: No module named的解决办法 、ImportError: No module named *** 问题?——理解绝对导入和相对导入 受到启发,然后修改代码:
PyRun_SimpleString("import sys");
PyRun_SimpleString("import cv2");
PyRun_SimpleString("import numpy as np");
PyRun_SimpleString("sys.path.append(r'../Python')");
//PyRun_SimpleString("sys.path.append(r'../Python')"); 一定要放在tracker 和 detector 的前面,指明它们的工作目录
PyRun_SimpleString("import tracker");
PyRun_SimpleString("from detector import Detector");
PyRun_SimpleString("import os");
错误3:
Could not find platform independent libraries <prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007fc83087e300 (most recent call first):
debug:
添加 conda 虚拟环境的目录
Py_SetPythonHome(L"/xxx/3rdparty/anaconda/envs/deepsort_py37");
错误4: The _imagingft C module is not installed
参照 Python: The _imagingft C module is not installed错误的解决
错误5:
error: ‘import_array’ was not declared in this scope
import_array();
^~~~~~~~~~~~
解决方法:
参考: Python + C/C++ 嵌入式编程(2):基于Code::Blocks进行环境配置和开发(入门版)
cmakelist.txt 中修改如下:
include_directories(/xxx/anaconda/envs/deepsort_py37/include/python3.7m)
include_directories(/xxx/anaconda/envs/deepsort_py37/lib/python3.7/site-packages/numpy/core/include)
所在代码中添加以下头文件:
#include <Python.h>
#include <numpy/arrayobject.h>
后续错误:
anaconda/envs/deepsort_py37/lib/python3.7/site-packages/numpy/core/include/numpy/__multiarray_api.h:1532:151: error: return-statement with a value, in function returning 'void' [-fpermissive]
#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NULL; } }
^
/xxx/yolo_deepsort_test/main.cpp:133:5: note: in expansion of macro ‘import_array’
import_array();
^
参考:import_array()报错,返回值类型与函数类型不匹配
错误6: 待更新…