2016-07-21 4 views
2

Ich versuche Scikit lernen in meinem C++ Projekt zu verwenden. Hier ist der Code Ich verwende:Python C API PyObject_Repr Segmentierungsfehler (Core Dumped)

#include <Python.h> 
    PyObject* loadModule(char* name)// 
    { 
     PyObject* pName = PyString_FromString(name); 
     PyObject* pModule = PyImport_Import(pName); 
     Py_DECREF(pName); 
     return pModule; 
    } 
    void displayPyObject(PyObject* object) 
    { 

    PyObject* objectsRepresentation = PyObject_Repr(object); 
    PyErr_Print(); 
    const char* s = PyString_AsString(objectsRepresentation); 
    PyErr_Print(); 
    std::cout << "[ PYOBJECT ]" << s << std::endl; 

    } 
    //load functions/ attributes from module 
    PyObject* loadComponentFromModule(char* module, char* component) 
    { 
     PyObject* pModule = loadModule(module); 
     PyObject* pyComponent = PyObject_GetAttrString(pModule, component); 
     Py_DECREF(pModule); 
     return pyComponent; 
    } 


    //WRAPPER FOR KMEANS CLUSTERING FROM SCIKIT-LEARN 
class KMeans 
{ 
public: 
    KMeans(int nClusters) 
    { 

     PyObject* KmeansClass = loadComponentFromModule("sklearn.cluster", "KMeans"); 
     PyObject* pName2 = PyInt_FromLong((long) nClusters); 
     PyObject* pArgs = PyTuple_New(1); 
     PyTuple_SetItem(pArgs, 0, pName2); 
     _Kcluster = PyObject_CallObject(KmeansClass, pArgs); 
     _closestor = loadComponentFromModule("sklearn.metrics","pairwise_distances_argmin_min"); 
     Py_DECREF(KmeansClass); 
     Py_DECREF(pName2); 
     Py_DECREF(pArgs); 
    } 
    ~KMeans() 
    { 
     Py_DECREF(_Kcluster); 
     Py_DECREF(_closestor); 
    } 

    void setNumClusters(int nClusters) 
    { 
     std::cout << "change to number cluster: " << nClusters << "\n"; 
     PyObject* nCluster = PyInt_FromLong((long) nClusters); 
     int code = PyObject_SetAttrString(_Kcluster,"n_clusters", nCluster); 
     PyErr_Print(); 
     if (code == -1) 
     { 
      std::cout << "[Error] KMeans.setNumClusters() Failed!! - Number of clusters didn't change!!\n"; 
     } 
     Py_DECREF(nCluster); 
    } 




    void info() 
    { 
     displayPyObject(_Kcluster); 
    } 

private: 
    PyObject* _Kcluster; 
    //PyObject* _result; 
    PyObject* _closestor; 
}; 

PyObject* loadClassifier() 
{ 
    PyObject* loader = loadComponentFromModule("sklearn.externals.joblib", "load"); 
    PyObject* pName2 = PyString_FromString("lda.pkl"); 
    PyObject* pArgs = PyTuple_New(1); 
    PyTuple_SetItem(pArgs, 0, pName2); 
    PyObject* clf = PyObject_CallObject(loader, pArgs); 
    Py_DECREF(loader); 
    Py_DECREF(pName2); 
    Py_DECREF(pArgs); 
// displayPyObject(clf); 
    return clf; 
} 

void produce_error() 
{ 
    std::cout << "============================= LINE 0 =========================================\n"; 
    PyObject* clf = loadClassifier();//"sklearn.externals.joblib", "load"); 
    std::cout << "============================= LINE 1 =========================================\n"; 
    KMeans cluster(8); 
    std::cout << "============================= LINE 2 =========================================\n"; 
    cluster.setNumClusters(5); 
    std::cout << "============================= LINE 3 =========================================\n"; 
    cluster.info(); 
    std::cout << "============================= LINE 4 =========================================\n"; 

} 

int main(int argc, char *argv[]) 
{ 
    Py_Initialize(); 
    produce_error(); 
    Py_Finalize(); 
    return 0; 
} 

Jedes Mal, wenn ich dieses Programm ausführen, bekomme ich die Fehlermeldung:

============================= LINE 0 ========================================= 
============================= LINE 1 ========================================= 
Segmentation fault (core dumped) 

Soweit ich verstehen, ohne den Klassifikator zu nennen, kann ich nicht bekomme irgendeinen Fehler, aber jedes Mal, wenn ich ihn anrufe (loadClassifier()) und eine Instanz von KMeans erstelle, wird der Fehler angezeigt. Irgendwann ist der Fehler innerhalb des Konstruktors von KMeans, wo ich das Modul mit dem gleichen Code in einer anderen Funktion (die nicht hier ist) geladen habe, der Fehler liegt in PyObject_Repr() (in displayPyObject()).

Wer hat schon mal das gleiche Problem? Weißt du, wie man es löst? Danke im Voraus.

Antwort

2

Problem gelöst. Ich habe es herausgefunden. Also antworte hier für die Zukunft, wenn jemand braucht. Vorsicht, wenn Sie Py_DECREF() verwenden. Das Problem kommt von dieser Linie innerhalb des Konstruktors von KMeans:

Py_DECREF(pName2);

Denn wenn man die Py_DECREF (pargs) laufen; es wird versuchen, pName2 freizugeben, das bereits freigegeben wurde. Es wird ein unvorhersehbares Verhalten verursachen. Nachdem diese Zeile kommentiert wurde, läuft alles gut.

Verwandte Themen