मुझे अजगर फ़ाइल द्वारा फ़ंक्शन नाम और हस्ताक्षर की सूची प्राप्त करने की आवश्यकता है। पायथन फ़ंक्शन inspect.signature मुझे फ़ंक्शन हस्ताक्षर प्राप्त कर सकता है। लेकिन inspect.signature को एक फंक्शन ऑब्जेक्ट (PyFunctionObject) की जरूरत है। inspect.getmembers ऐसी वस्तु लौटा सकता है। लेकिन अगर मैं PyFunctionObject को PyTuple में आइटम के रूप में सेट करता हूं, जब Py_Finalize निष्पादित होता है - मुझे त्रुटि मिलती है। इसके अलावा, मैं क्यूटी का उपयोग कर रहा हूँ।

तो लाइन PyTuple_SetItem(pFuncLink_arg, 0, pGetmember_tupleList); परिणाम त्रुटि।

कोड:।

PyObject *pName, *pModule;
PyObject *pInspect_module_name, *pInspect_module;
PyObject *pGetmember_function, *pGetmember_call_args, *pGetmembers_reply, *pGetsignature_function, *pGetmember_itemList, *pGetmember_tupleList;
PyObject *pFuncName, *pFuncLink_arg, *pFuncSign;

Py_Initialize();

QFileInfo fileInfo(QFile("X:/Projects/p-text.py"));
QString absPath = fileInfo.absolutePath();

QString fileName = fileInfo.baseName();

PyObject* sysPath = PySys_GetObject((char*)"path"); 
PyObject* programName = PyUnicode_FromString(absPath.toAscii());
PyList_Append(sysPath, programName);

pName = PyUnicode_FromString(fileName.toLatin1());
pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL){
    pInspect_module_name = PyUnicode_DecodeFSDefault("inspect");
    pInspect_module = PyImport_Import(pInspect_module_name);
    pGetmember_function = PyObject_GetAttrString(pInspect_module, "getmembers");    
    pGetsignature_function = PyObject_GetAttrString(pInspect_module, "signature");

    pGetmember_call_args = PyTuple_New(1);
    PyTuple_SetItem(pGetmember_call_args, 0, pModule);
    pGetmembers_reply = PyObject_CallObject(pGetmember_function, pGetmember_call_args);

    if (pGetmembers_reply){
        Py_ssize_t const num_args = PyList_Size(pGetmembers_reply);
        for (Py_ssize_t i = 0; i < num_args; ++i){
            pGetmember_itemList = PyList_GetItem(pGetmembers_reply, i);
            pGetmember_tupleList =  PyTuple_GetItem(pGetmember_itemList, 1);

            if (PyFunction_Check(pGetmember_tupleList)){
                pFuncName =  PyTuple_GetItem(pGetmember_itemList, 0);
                QString funcName = PyObjectToString(pFuncName);
                    Py_DECREF(pFuncName);

                pFuncLink_arg = PyTuple_New(1);
                PyTuple_SetItem(pFuncLink_arg, 0, pGetmember_tupleList);

                pFuncSign = PyObject_CallObject(pGetsignature_function, pFuncLink_arg);

                if (pFuncSign == NULL) {
                    if (PyErr_Occurred()) {
                        PyErr_Print(); 
                    }
                    return;
                }

                QString funcSign = PyObjectToString(pFuncSign);

                Py_DECREF(pFuncSign);

                cout<<funcSign.toStdString()<<endl;
            }

            Py_DECREF(pGetmember_tupleList);
            Py_DECREF(pGetmember_itemList);
        }
    }
    Py_DECREF(pInspect_module_name);
    Py_DECREF(pInspect_module);
    Py_DECREF(pGetmember_function);
    Py_DECREF(pGetsignature_function);
    Py_DECREF(pGetmember_call_args);
}
else {
    PyErr_Print();
}

Py_Finalize();

Py_Finalize() एक त्रुटि फेंकता है "project_name.exe ने ब्रेकपॉइंट ट्रिगर किया है"

0
Nukopol 17 अक्टूबर 2019, 17:01

1 उत्तर

सबसे बढ़िया उत्तर

संदर्भ गणना त्रुटि।

PyTuple_GetItem "उधार लिया गया संदर्भ" देता है ". आप pGetmember_tupleList के स्वामी नहीं हैं।

PyTuple_SetItem (इसे उसी लिंक पर ढूंढें...) "एक संदर्भ चुराता है", यानी मान लें कि कॉल से पहले आपके पास pGetmember_tupleList है, लेकिन कॉल के बाद आपके पास इसका स्वामित्व नहीं है।

इसे प्राप्त करने के बाद आपको एक Py_INCREF(pGetmember_tupleList) जोड़ना होगा।


आपके पास pFuncName के साथ एक अलग, संबंधित संदर्भ गणना त्रुटि है - आप एक उधार संदर्भ को डिक्रिप्ट करते हैं जो आपके पास नहीं है। मुझे संदेह है कि शायद यहां अन्य संदर्भ गिनती त्रुटियां भी हैं ...


आपको कोई त्रुटि जाँच भी नहीं है; यह देखने के लिए कि क्या यह एक अपवाद (आमतौर पर NULL सूचक के लिए) उठाया गया है, लगभग हर पायथन कॉल के बाद चेक किया जाना चाहिए।

1
DavidW 17 अक्टूबर 2019, 23:11