C++ 中调用执行Python文件

1 篇文章 0 订阅

在编写项目的过程中,需要在c++下调用一个python模块,现在将方法整理一下,留存备用。

首先需要导入对应的头文件 :

  #include <python2.7/Python.h>

接下来是代码实现部分:

        

//初始化python运行环境
        Py_Initialize();   
        //将python的执行目录切换到当前目录下
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");

        //定义一些需要使用到的变量
	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	PyObject* pParam = NULL;
        //这里由于我的python方法返回值是一个比较复杂的结果,所以我定义了很多result变量用于处理返回值
	PyObject* pResult = NULL;//接收最外层的结果
	PyObject* pSingleResult = NULL;//拆分最外层结果为单条结果
	PyObject* pSingleResult_Content = NULL;//取单条结果的LIST的某个字段
	PyObject* pResultCodeStr = NULL;//取单条结果的检测代码List的某个字段

	const char* pBuffer = NULL;
	int iResult = 0;


	//导入py文件
	pModule = PyImport_ImportModule("文件名(不需要带后缀.py)");
	if (!pModule) {
		exit (0);
	}


	//根据函数名,取出python文件中函数,后面将会有调用这个函数的时候
	pFunc = PyObject_GetAttrString(pModule, "函数名(不需要带参数列表,也不要加括号)");
        if (!pFunc){  //  || !PyCallable_Check(pFunc)
		exit (0);
	}


       //生成一个参数变量
       //第一个参数为变量类型
       //  s 表示字符串,
       //  i 表示整型变量,
       //  f 表示浮点数,
       //  O 表示一个Python对象。
       //支持一个生成多个对象
       //例如:  pArgs = Py_BuildValue("ii", 12, 14);
       pParam = Py_BuildValue("(ss)", htmlCode.c_str(),rules.c_str());


        //使用刚才取出来的函数对象,调用函数,传递刚建立的参数对象,并接收返回值
       pResult = PyEval_CallObject(pFunc,pParam);


       // PyArg_Parse 把python对象,按照第二个参数的类型取出来,保存至第三个变量中。第二个参数是拆分出来的类型,后面跟着的是赋值的对象
       // PyList_Size 获取python中list的长度(对象个数)
       //PyList_GetItem(python List对象,对象的index值,从0开始) 即取出list中的某个元素
	if(pResult)
	{
		iResult = PyList_Size(pResult);
		 for(int i=0;i<iResult;i++){
                         //yaraResult 是我自己定义的一个类,用于将python的返回值保存为方便使用的格式
			 yaraResult yaraRet;
			 pSingleResult = PyList_GetItem(pResult,i);
			 //接下来的操作都是用于取出Python的结果值,因为返回值是不断嵌套的list 和 set ,会比较麻烦
			 pSingleResult_Content = PyList_GetItem(pSingleResult,4);
			 if(PyArg_Parse(pSingleResult_Content, "s", &pBuffer)){
			   yaraRet.name = pBuffer;
			 }
			 //
			 pSingleResult_Content = PyList_GetItem(pSingleResult,1);
			 if(PyArg_Parse(pSingleResult_Content, "(s)", &pBuffer))
			   yaraRet.flawname = pBuffer;
			 //
			 pSingleResult_Content = PyList_GetItem(pSingleResult,2);
			 int iStrCount = PyList_Size(pSingleResult_Content);
			 for(int j=0;j<iStrCount;j++){
				 pResultCodeStr = PyList_GetItem(pSingleResult_Content,j);
				 if(PyArg_Parse(pResultCodeStr, "s", &pBuffer))
						yaraRet.flawCode = yaraRet.flawCode + ' ' + pBuffer;
			   }//end_for_PyList_Size(pCheckResultStr);
			 result.push_back(yaraRet);
		 }//end_for_PyList_Size(pResult)
	}//end_if_if(pResult)

        //使用结束后,释放掉这些Python对象
	if(pModule)
		Py_DECREF(pModule);
	if(pFunc)
			Py_DECREF(pFunc);
	if(pParam)
			Py_DECREF(pParam);
	if(pResult)
			Py_DECREF(pResult);
	if(pSingleResult)
			Py_DECREF(pSingleResult);
	if(pSingleResult_Content)
			Py_DECREF(pSingleResult_Content);
	if(pResultCodeStr)
			Py_DECREF(pResultCodeStr);
        //结束掉python的运行环境
	Py_Finalize();
	return result;
}

在使用过程中,发现了 PyArg_Parse 的一个特殊的地方。
 PyArg_Parse(pResult ,"s", &pBuffer))
 PyArg_Parse(pResult, "(s)", &pBuffer))
这两种取值方式是不同的。
第一种方式是将python对象直接强制转换成字符串类型,然后输出
第二种方式是将python对象看作是一个set,然后取出这个set的值,作为字符串输出。
因此有时候,在使用PyArg_Parse的时候可能没法正确的取出值,这个时候可以考虑一下是不是参数的设置问题。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值