2013-04-02 38 views
1

下面是C++代码,它会在同一个目录中调用我的python脚本'rule.py'。第二次调用时无法从python模块获取函数

#include <Python.h> 
#include <iostream> 
using namespace std; 

int dou(int a) 
{ 
    PyObject *pModule, *pDict, *pFunc, *pArgs, *pRetVal; 
    if(!Py_IsInitialized()){ 
     cout<<"Can't initialize"<<endl; 
     return -1; 
    } 
    PyRun_SimpleString("import sys"); 
    PyRun_SimpleString("sys.path.append('.')"); 
    pModule = PyImport_ImportModule("rule"); 
    if(!pModule){ 
     cout<<"can' import the module "<<endl; 
     return -1; 
    } 
    pDict = PyModule_GetDict(pModule); 
    if(!pDict){ 
     cout<<"can't get the dict"<<endl; 
     return -1; 
    } 
    pFunc = PyDict_GetItemString(pDict, "fun"); 
    if(!pFunc || !PyCallable_Check(pFunc)){ 
     cout<<"can't get the function"<<endl; 
     return -1; 
    } 

    pArgs = PyTuple_New(1); 
    PyTuple_SetItem(pArgs,0,Py_BuildValue("i",a)); 
    pRetVal = PyObject_CallObject(pFunc,pArgs); 

    int result = PyInt_AsLong(pRetVal); 

    Py_DECREF(pModule); 
    Py_DECREF(pDict); 
    Py_DECREF(pFunc); 
    Py_DECREF(pArgs); 
    Py_DECREF(pRetVal); 

    return result; 
} 
int main(void) 
{ 
    Py_Initialize(); 
    cout<<dou(2)<<endl; 
    cout<<dou(3)<<endl; 
    Py_Finalize(); 
    return 0; 
} 

这就是简单的python代码。

def fun(a): 
    return 2*a 
if __name__ == "__main__": 
    print fun(2) 

输出是:

4 
can't get the function. 
-1 

它工作在第一时间,但是当第二次调用它不能得到的功能。也许我错过了什么?

+1

演示代码在异常中返回时会导致内存泄漏,并且它在python doc中使用Py_XDECREF(pFunc),但这对此问题无效。 – luxiaolu

回答

2

PyModule_GetDict()返回借来的参考。这意味着你不能减少其引用计数,否则模块字典将被破坏。

你的代码片段有很多错误。我认为你可以尝试boost :: python。仔细阅读Python手册,尤其是参考计数管理。

+0

我只是再次阅读文档并使用'pFunc = PyObject_GetAttrString(pModule,Func_name)'来替换'pDict = PyModule_GetDict(pModule)'来获取函数对象。有用!前一个将返回一个新的参考,另一个将返回一个借来的参考,正如你所说的。但是,如果我仍然使用旧的方法来获取函数并删除'Py_XDECREF(pFunc)'狗屎仍然存在,我不知道为什么。 – luxiaolu

相关问题