C++调用python(二)
目录
正文
一、基本使用方法
二、调用简单语句
三、调用函数
四、调用类
五、调用SSD目标检测算法
六、遇到的错误
三、调用函数
3.1 无参
-CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project(say_hello)
set(SDK_VERSION 0_0_1)
# >>> build type
set(CMAKE_BUILD_TYPE "Release")# 指定生成的版本
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# <<<
# >>> CXX11
set(CMAKE_CXX_STANDARD 11)# C++ 11 编译器
SET(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# <<<
# >>> Python3
set(PYTHON_ROOT "/home/zjh/anaconda3/envs/learn")
message("python root: " ${PYTHON_ROOT})
include_directories(${PYTHON_ROOT}/include/)
link_directories(${PYTHON_ROOT}/lib/)
# <<<
# --- generate ---
add_executable(say_hello hello.cpp)
target_link_libraries(say_hello -lpython3.6m)
- hello.py
def say():
print("hello")
if __name__ == "__main__":
say()
- hello.cpp
#include <python3.6m/Python.h>
#include <iostream>
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
if ( program == nullptr ){
std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
return -1;
}
Py_SetProgramName(program);
Py_SetPythonHome((wchar_t*)L"/home/zjh/anaconda3/envs/learn");
Py_Initialize();
if ( !Py_IsInitialized() ){
std::cout << "Python init failed!" << std::endl;
return 0;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/media/zjh/code/C++_call_python/test/test_hello')");
PyObject* pModule = PyImport_ImportModule("hello");
if ( pModule == nullptr ){
std::cout << "module not found!" << std::endl;
return 1;
}
PyObject* pFunc = PyObject_GetAttrString(pModule, "say");
if ( !pFunc || !PyCallable_Check(pFunc) ){
std::cout << "not found function add_num!" << std::endl;
return 2;
}
PyObject_CallObject(pFunc, nullptr);
if ( Py_FinalizeEx() < 0 ){
exit(120);
}
PyMem_RawFree(program);
return 0;
}
3.2 有参
-
CMakeLists.txt
在3.1的基础上修改开始的program 和最后generate
部分就行。 -
add.py
def add_num(a, b):
print("the result {} + {} is {}".format(a, b, a+b))
return a + b
if __name__ == "__main__":
add_num(1, 2)
- add.cpp
#include <python3.6m/Python.h>
#include <iostream>
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
if ( program == nullptr ){
std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
return -1;
}
Py_SetProgramName(program);
Py_Initialize();
if ( !Py_IsInitialized() ){
std::cout << "Python init failed!" << std::endl;
return 0;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/work/C++_python/test/test_add')");
PyObject* pModule = PyImport_ImportModule("add");
if ( pModule == nullptr ){
std::cout << "module not found!" << std::endl;
return 1;
}
PyObject* pFunc = PyObject_GetAttrString(pModule, "add_num");
if ( !pFunc || !PyCallable_Check(pFunc) ){
std::cout << "not found function add_num!" << std::endl;
return 2;
}
PyObject* args = Py_BuildValue("(ii)", 28, 103);
PyObject* pRet = PyObject_CallObject(pFunc, args);
Py_DECREF(args);
int res = 0;
PyArg_Parse(pRet, "i", &res);
Py_DECREF(pRet);
std::cout << "the res is: " << res << std::endl;
if ( Py_FinalizeEx() < 0 ){
exit(120);
}
PyMem_RawFree(program);
return 0;
}
四、调用类
-
CMakeLists.txt
-
test_class.py
class Test(object):
def __init__(self):
self.i = 1
print("init!")
def modify(self):
self.i += 1
def do(self):
print(self.i)
if __name__ == "__main__":
test_class = Test()
test_class.do()
test_class.modify()
test_class.do()
- testClass.cpp
#include <python3.6m/Python.h>
#include <iostream>
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
if ( program == nullptr ){
std::cout << "Fatal Error: cannot decode argv[0]!" << std::endl;
return -1;
}
Py_SetProgramName(program);
Py_Initialize();
if ( !Py_IsInitialized() ){
std::cout << "Python init failed!" << std::endl;
return 0;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/work/C++_python/test/test_class')");
// 1. 导入模块
PyObject* pModule = PyImport_ImportModule("test_class");
if ( pModule == nullptr ){
std::cout << "module not found!" << std::endl;
return 1;
}
PyObject* pTestDict = PyModule_GetDict(pModule);
// 2. 导入模块中方法或类
PyObject* pTestClass = PyDict_GetItemString(pTestDict, "Test");
// 3. 创建实例
PyObject* pTestInstance = nullptr;
if ( PyCallable_Check(pTestClass) ){
pTestInstance = PyObject_CallObject(pTestClass, nullptr);
}
// 4. 调用类方法
PyObject_CallMethod(pTestInstance, "do", nullptr);
PyObject_CallMethod(pTestInstance, "modify", nullptr);
PyObject_CallMethod(pTestInstance, "do", nullptr);
if ( Py_FinalizeEx() < 0 ){
exit(120);
}
PyMem_RawFree(program);
return 0;
}
注:如果类函数有参数,可以参照4.2中方法