C++ 中调用执行Python文件

来源:互联网 发布:java finalize作用 编辑:程序博客网 时间:2024/05/19 20:39

在编写项目的过程中,需要在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的时候可能没法正确的取出值,这个时候可以考虑一下是不是参数的设置问题。


0 0