2009-09-13 102 views
7

我想從我的主C++程序調用Python腳本中的函數。 python函數接受一個字符串作爲參數,並返回任何內容(ok ..'None')。 只要先前的調用在再次調用函數之前完成,它就可以很好地工作(從來沒有想過會這麼簡單..),否則在pModule = PyImport_Import(pName)有訪問衝突。從C++調用Python

有很多教程如何在C中嵌入python,反之亦然,但我沒有發現任何關於這個問題。

int callPython(TCHAR* title){ 
    PyObject *pName, *pModule, *pFunc; 
    PyObject *pArgs, *pValue; 

Py_Initialize(); 
    pName = PyUnicode_FromString("Main"); 
    /* Name of Pythonfile */ 

    pModule = PyImport_Import(pName); 
    Py_DECREF(pName); 

if (pModule != NULL) { 
     pFunc = PyObject_GetAttrString(pModule, "writeLyricToFile"); 
     /* function name. pFunc is a new reference */ 
     if (pFunc && PyCallable_Check(pFunc)) { 
      pArgs = PyTuple_New(1); 

    pValue = PyUnicode_FromWideChar(title, -1); 

    if (!pValue) { 
     Py_DECREF(pArgs); 
       Py_DECREF(pModule); 
     showErrorBox(_T("pValue is false")); 
     return 1; 
      } 
    PyTuple_SetItem(pArgs, 0, pValue); 

      pValue = PyObject_CallObject(pFunc, pArgs); 
      Py_DECREF(pArgs); 

      if (pValue != NULL) { 
       //worked as it should! 
       Py_DECREF(pValue); 
      } 
      else { 
       Py_DECREF(pFunc); 
       Py_DECREF(pModule); 
       PyErr_Print(); 
     showErrorBox(_T("pValue is null")); 
     return 1; 
      } 
     } 
     else { 
      if (PyErr_Occurred()) PyErr_Print(); 
      showErrorBox(_T("pFunc null or not callable")); 
     return 1; 
     } 
     Py_XDECREF(pFunc); 
     Py_DECREF(pModule); 
    } 
    else { 
     PyErr_Print(); 
     showErrorBox(_T("pModule is null")); 
    return 1; 
    } 
    Py_Finalize(); 
    return 0; 
} 

回答

5

當你說「只要函數被再次調用之前,以前的通話結束」,我只能假設你有多個線程C++成Python調用。 python不是線程安全的,所以這將會失敗!

閱讀Python手冊中的全局解釋器鎖(GIL)。也許下面的鏈接將幫助:

的GIL是維基百科上提到:

1

謝謝你的幫忙!

是的,你是對的,有幾個C線程。從來沒有想過我會爲解釋器本身需要互斥體--GIL對我來說是一個全新的概念(甚至在整個教程中都沒有提及過)。

讀取基準(肯定不是它的最容易的部分,雖然PyGILState_ *功能簡化了整個事情很多)之後,我添加了一個

void initPython(){ 
    PyEval_InitThreads(); 
    Py_Initialize(); 
    PyEval_ReleaseLock(); 
} 

功能正確初始化解釋。每個線程創建其數據結構,獲取鎖定並在之後釋放它,如參考文獻中所示。

按原樣工作,但在終止該過程之前調用Py_Finalize()時,我得到一個段錯誤..只是離開它的任何問題?

+2

我很高興這已解決您的問題。我不認爲你爲什麼會調用Py_Finalize() - 也許你可以提供一個簡化的例子來展示另一個問題。你真的應該關閉Python,但如果你只是要退出應用程序,你可能會很好......我強烈建議你找出它爲什麼崩潰。 – 2009-09-14 00:11:16

+0

@DanielPaull可以請你給一個簡單的工作例子,以上相同的話題。所以我可以很容易地理解 – lkkkk 2014-05-13 05:55:39