代码之家  ›  专栏  ›  技术社区  ›  Voo

从C++调用Python

  •  7
  • Voo  · 技术社区  · 15 年前

    我试图从我的C++程序中调用一个Python脚本中的函数。python函数以字符串作为参数,不返回任何内容(ok..'None')。 只要在再次调用函数之前完成上一次调用,它就可以很好地工作(没想到会那么容易…),否则在 pModule = PyImport_Import(pName)

    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;
    }
    
    2 回复  |  直到 11 年前
        2
  •  1
  •   Voo    15 年前

    是的,你是对的,有几个C线程。从来没有想过我会为解释器本身需要互斥-GIL对我来说是一个全新的概念(在整个教程中甚至一次都没有提到)。

    在阅读了参考之后(当然不是最简单的部分,尽管PyGILState_*函数简化了整个过程),我添加了一个

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

    函数正确初始化解释器。 每个线程创建其数据结构,获取锁,然后释放锁,如参考中所示。

    正常工作,但在终止进程之前调用Py_Finalize()时,我会得到一个segfault。。离开有什么问题吗?