使用C++调用python3

使用C++调用python3

正常使用流程

  • 第一步:包含头文件
 #include <python3.6m/Python.h>
  • 第二步: 初始化Python解释器
Py_Initialize();
  • 第三步:设置要调用的python文件路径
PyRun_SimpleString("import sys");//执行import语句
PyRun_SimpleString("sys.path.append('/home/xx/src')");
  • 第四步:加载xx.py文件,注意不要加上后缀
pModule = PyImport_ImportModule("xx");//xx.py
  if(pModule == NULL)
  {
      PyErr_Print();
      return;
  } 
  • 第五步:加载python中定义initRobot函数
 PyObject * pInitRobot = PyObject_GetAttrString(pModule,"initRobot");
  if(pInitRobot == NULL)
  {
      PyErr_Print();
      return;
  }
  • 第六步:执行python中定义initRobot函数,无参直接可以PyObject_CallObject的第二个参数可以写为nullptr
PyObject_CallObject(pInitRobot, nullptr);
  • 第七步:释放声明的PyObject,及释放解析器
   Py_DECREF(pInitRobot);
   Py_DECREF(pModule);
   Py_Finalize();

需要传入参数到python

  • 需要传入python的参数为list的
    PyObject *PyList  = PyList_New(7);//定义一个与数组等长的PyList对象数组
    PyObject *ArgList = PyTuple_New(1);//定义一个Tuple对象,Tuple对象的长度与Python函数参数个数一致,上面Python参数个数为1,所以这里给的长度为1
    
    //移动机械臂MovJ到这个位姿下去
   //给PyList对象的每个元素赋值
    PyList_SetItem(PyList, 0, PyFloat_FromDouble(xyz.x()));
    PyList_SetItem(PyList, 1, PyFloat_FromDouble(xyz.y()));
    PyList_SetItem(PyList, 2, PyFloat_FromDouble(xyz.z()));
    PyList_SetItem(PyList, 3, PyFloat_FromDouble(quaternion.w()));    
    PyList_SetItem(PyList, 4, PyFloat_FromDouble(quaternion.x()));
    PyList_SetItem(PyList, 5, PyFloat_FromDouble(quaternion.y()));
    PyList_SetItem(PyList, 6, PyFloat_FromDouble(quaternion.z()));
    PyTuple_SetItem(ArgList, 0, PyList);//将PyList对象放入PyTuple对象中

    PyObject_CallObject(pMovJ,ArgList);
    Py_DECREF(PyList);
    Py_DECREF(ArgList);
    
  • 需要传入python的参数为整型的
 PyObject *pArg = PyTuple_New(1);
 PyTuple_SetItem(pArg, 0, Py_BuildValue("i", 1));//0—序号 i表示创建int型变量
 PyObject_CallObject(pEnableMotor, pArg);

处理python返回值

  • 需要处理从python返回为list到c++的
PyObject * p_pose = PyObject_CallObject(pGetCurrentPose, nullptr);
 if(p_pose == nullptr)
 {
     ROS_ERROR("Error: p_pose == nullptr");
     PyErr_Print();
     return false;
 }
  std::vector<double> v_current_pose;
  if(p_pose && PyList_Check(p_pose))
 {
		int i_size = PyList_Size(p_pose);
		if(i_size <= 0)
		{
		    ROS_ERROR("获取机械臂当前位姿失败");
		    return false;
		}
     	for (int i = 0; i < i_size; ++i)
	     {
	         PyArg_Parse(PyList_GET_ITEM(p_pose, i), "d", &temp);
	         v_current_pose.push_back(temp);
	     }
    	 if(v_current_pose.size() != 7)
    	 {
         ROS_ERROR("获取机械臂当前位姿包含变量为:%d",(int)v_current_pose.size() );
         return false;
    	 }
}

注:如果python脚本执行出错,会导致PyObject_CallObject返回值为nullptr

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值