2011-01-14 12 views
4

Dies ist mein erster Beitrag :). Ich könnte ein erweitertes Python-Objekt in einen C++ - Zeiger konvertieren, aber ich habe ein Problem. Zuerst zeige ich dir meinen Code und dann erkläre ich das Problem.Python-Objekt zu C++ - Zeiger Problem

Das ist meine Klasse:

#include <boost/python.hpp> 


using namespace boost::python; 


class Base 
{ 

public: 

    virtual const char* HelloWorld() = 0; 

}; 


class BaseWrapper : public Base, public wrapper<BaseWrapper> 
{ 

public: 

    virtual const char* HelloWorld() 
    { 

     if (override f = this->get_override("HelloWorld")) 
      return call<const char*>(f.ptr()); 

     return "FAILED TO CALL"; 

    } 

}; 

Boost-Verpackung:

BOOST_PYTHON_MODULE(hello_ext) 
{ 

    class_<Base, boost::noncopyable>("Base", no_init); 

    class_<BaseWrapper, bases<Base> >("BaseWrapper") 
     .def("HelloWorld", &BaseWrapper::HelloWorld); 

} 

Der Python-Code (hello.py):

def NewDerived(): 
    import hello_ext 

    class Derived(hello_ext.BaseWrapper): 
     def __init__(self): 
       super(Derived, self).__init__() 
     def HelloWorld(self): 
       return "This is a Hello World!!!" 

    return Derived() 

und die Hauptdatei:

int main() 
{ 

    // Start the interpreter. 
    Py_Initialize(); 

    // Import the module that we need (hello.py) 
    object module = import("hello"); 

    // Get a C++ pointer of the derived python class. 
    Base* base = extract< Base* >(module.attr("NewDerived")()); 

    // Call the HelloWorld function 
    std::cout << base->HelloWorld() << std::endl; 

} 

Wenn ich meine Anwendung ausführen, kann ich auf dem Bildschirm sehen "Dies ist eine Hallo Welt !!!" wie ich erwartet habe. Also, was ist das Problem ??? Angenommen, ich die Python-Code zu ändern:

def NewDerived(): 
    import hello_ext 

    class Derived(hello_ext.BaseWrapper): 
     def __init__(self): 
       super(Derived, self).__init__() 
     def HelloWorld(self): 
       return "This is a Hello" # I CHANGED THIS LINE!!!! 

    return Derived() 

Dann, wenn ich meine Anwendung laufen wieder, es stürzt ab, weil ich einen Fehler in der Leitung bekam:

std::cout << base->HelloWorld() << std::endl; 

weil Basis NULL ist.

Genauer gesagt, ist der Fehler "Zugriffsverletzung lesen Speicherort 0xblablabla". Wenn ich debuggen, stoppt die debugguer an der Funktion (Boost-oder Python-Code, denke ich)

inline api::object_base::~object_base() 
{ 
    Py_DECREF(m_ptr); 
} 

Was denken Sie ???

Antwort

2

Schließlich erklärte mir ein anderer Programmierer die Lösung.

Ich weiß nicht, warum es ursprünglich funktioniert hat, aber das Problem ist, dass das Objekt zerstört wird, bevor ich versuche, die Member-Funktion aufzurufen. Ich brauche den Extrakt Anruf in zwei Teile zu brechen, wie so:

object derived = module.attr("NewDerived")(); 
Base* base = extract< Base* >(derived); 

Damit wird das Objekt halten lange genug für mich tatsächlich auf sie Funktionen aufzurufen.