2014-06-30 38 views
3

返回一個長整型嗨,我試圖從嵌入式Python返回值(119599936)到C++無法從嵌入式Python到C++

Py_Initialize(); 
PyObject* myModuleString = PyString_FromString((char*)"memory_leak_test"); 
PyObject* myModule = PyImport_Import(myModuleString); 
PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"begin"); 
PyObject* args = PyTuple_Pack(1,PyString_FromString("CacheSetup")); 
PyObject* myResult = PyObject_CallObject(myFunction, args); 
double result = PyFloat_AsDouble(myResult);// <<<<<<<<< I guess thts where i'm goin wrong 
std::cout << result << std::endl; 
Py_Finalize(); 

我試過

unsigned long result = PyLong_AsUnsignedLong(myResult); 
unsigned long long result = PyLong_AsUnsignedLongLongMask(myResult); 
double result = PyLong_AsDouble(myResult2); 

無上面似乎工作的時候,當我嘗試返回數字119599936,我得到的錯誤是

Exception SystemError: '..\\Objects\\longobject.c:739: bad argument to internal 
function' in 'garbage collection' ignored 
Fatal Python error: unexpected exception during garbage collection 

回答

1

由於您的代碼perfo rms不檢查任何錯誤,並且你不提供源到memory_leak_test模塊,任何人都可以猜測出了什麼問題。我的猜測是memory_leak_test無法導入,或者memory_leak_test.begin("CacheSetup")引發異常或返回None,而不是像您的代碼所期望的那樣返回一個數字。

要調試這個問題時,應牢記以下原則改寫:在Python/C函數可以返回他們

  • 檢查錯誤。每當一個錯誤你不能處理出現,打電話PyErr_Print()並終止當前執行的(除非您所期待的錯誤,並希望妥善處理它 - 在這種情況下,調用PyErr_Clear()代替。)

  • 調用Py_DECREF上的對象返回new references一旦你不再需要它們。這些的例子是PyString_FromStringPyTuple_PackPyObject_CallOject的返回值。

  • 瞭解的和方便使用的功能,例如PyObject_CallFunctionPyObject_CallMethod,和PyImport_ImportModule其顯著減少用於創建臨時字符串和元組樣板代碼。找到這些的最好方法是仔細閱讀現有的Python/C源代碼,例如Python提供的源代碼。

  • 使用PyObject_Print()打印調試的中間結果。

下面是根據上面的一個代碼的可能的修改:

Py_Initialize(); 

PyObject *module = PyImport_ImportModule("memory_leak_test"); 
if (!module) { 
    PyErr_Print(); 
    return; 
} 
PyObject *result = PyObject_CallMethod(module, "begin", "s", "CacheSetup"); 
Py_DECREF(module); 
if (!result) { 
    PyErr_Print(); 
    return; 
} 
printf("got result of type %s\n", Py_TYPE(result)->tp_name); 
PyObject_Print(result, stdout, 0); 
putchar('\n'); 

Py_DECREF(result); 
Py_Finalize();