2011-01-14 18 views
4

これは私の最初の投稿です:)。私はPythonの拡張オブジェクトをC++のポインタに変換できますが、問題があります。最初に私はあなたに私のコードを示して、問題を説明します。PythonオブジェクトからC++へのポインタ問題

これが私のクラスである:

#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_PYTHON_MODULE(hello_ext) 
{ 

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

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

} 

ザ・Pythonコード(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() 

とメインファイル:

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; 

} 

私はアプリケーションを実行すると、 "This is a Hello World !!!"という画面が表示されます。私の期待通りに。 それで、問題は何ですか?ベースがNULLであるため、

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

:私はラインでのエラーを得たので、私は、それがクラッシュし、再び自分のアプリケーションを実行すると、その後

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() 

:私はPythonのコードを変更するとします。

さらに正確には、エラーは「アクセス違反の読み取り場所0xblablabla」です。 私がデバッグ、debugguerは

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

あなたはどう思います(私が思うブーストまたはPythonコード)機能で停止???

答えて

2

最後に、別のプログラマが私に解決策を説明しました。

私はなぜそれがもともと働いたのか分かりませんが、問題は、メンバー関数を呼び出す前にオブジェクトが破壊されているということです。私は実際にそれで関数を呼び出すする

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

これは、周りの十分な長さのオブジェクトを保持します:私はそうのような二つの部分に抽出通話を切断する必要があります。

関連する問題