python示例如下:
# my_test.py
class Person:
def __init__(self):
self.name = 'wdx'
self.age = 23
def set_msg(self, name, age):
self.name = name
self.age = age
def get_msg(self):
print('python: name={}, age={}'.format(self.name, self.age))
return self.name, self.age
C++如下:
#include
...
int main(int a, char** b)
{
PyObject *pModule, *pDict, *pFRCNN, *pFrcnn;
PyObject *result, *result1;
//初始化python
Py_Initialize();
if (!Py_IsInitialized())
{
printf("python初始化失败!");
return 0;
}
//引入当前路径,否则下面模块不能正常导入
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('../tf-faster-rcnn/tools')");
//引入py文件
pModule = PyImport_ImportModule("my_test");
// pModule = PyImport_ImportModule("demo");
assert(pModule != NULL);
//获取模块字典,即整个py文件的对象
pDict = PyModule_GetDict(pModule);
assert(pDict != NULL);
//通过字典属性获取模块中的类
pFRCNN = PyDict_GetItemString(pDict, "Person");
// pFRCNN = PyDict_GetItemString(pDict, "Faster_RCNN");
assert(pFRCNN != NULL);
// 实例化faster-rcnn检测器
pFrcnn = PyObject_CallObject(pFRCNN, nullptr);
assert(pFrcnn != NULL);
PyRun_SimpleString("print('-'*10, 'Python start', '-'*10)");
// 调用类的方法
result = PyObject_CallMethod(pFrcnn, "get_msg", "");
PyObject_CallMethod(pFrcnn, "set_msg", "si", "tyl", 24);
result1 = PyObject_CallMethod(pFrcnn, "get_msg", "");
// 创建参数
// PyObject *pArgs = PyTuple_New(2); //函数调用的参数传递均是以元组的形式打包的,2表示参数个数
//输出返回值
char* name;
int age;
PyArg_ParseTuple(result, "si", &name, &age);
printf("%s-%d\n", name, age);
PyArg_ParseTuple(result1, "si", &name, &age);
printf("%s-%d\n", name, age);
PyRun_SimpleString("print('-'*10, 'Python end', '-'*10)");
//释放python
Py_DECREF(pFrcnn);
Py_Finalize();
}
1、python脚本里的路径都不要写相对路径!
如:cv2.imread('../data/demo/111.jpg') 错!!
要写绝对路径:cv2.imread('/home/.../data/demo/111.jpg')
2、
PyTuple_New创建的参数不可以重复赋值,否则最后的数据都是最后赋的值。
正确的示例:
// mat图像转PyObject格式
PyObject *Func::mat_to_pyobj(Mat &im) {
PyObject *pIm = PyTuple_New(int(im.rows)); // 图像数据
for (int row = 0; row < im.rows; row++) { // 行
PyObject *pRow = PyTuple_New(int(im.cols)); // 新建每一行
for (int col = 0; col < im.cols; col++) { // 列
PyObject *pPt = PyTuple_New(3); // 像素点 BGR
PyTuple_SetItem(pPt, 0, Py_BuildValue("i", static_cast(im.at(row, col)[0])));
PyTuple_SetItem(pPt, 1, Py_BuildValue("i", static_cast(im.at(row, col)[1])));
PyTuple_SetItem(pPt, 2, Py_BuildValue("i", static_cast(im.at(row, col)[2])));
PyTuple_SetItem(pRow, col, pPt); // 添加行像素
}
PyTuple_SetItem(pIm, row, pRow);
}
return pIm;
}
3、调用的python函数如果有返回值,不要只返回一个,至少返回两个
return result, 1
4、在ros中使用c++调用python时,要在cmakelists中包含以下部分
set(CMAKE_CXX_STANDARD 14)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
)
catkin_python_setup()
catkin_package(
CATKIN_DEPENDS
roscpp
rospy
)
target_link_libraries(mir100_jaco7_voice_record_node # 节点名
python3.5m
${catkin_LIBRARIES}
)
target_link_libraries(mir100_jaco7_voice_command_node # 节点名
python3.5m
${catkin_LIBRARIES}
)