Boost.Python and Boost.Signals2: Błędy segmentacji

Mam problem z integracją boost.signals2 w mojej istniejącej bibliotece C ++, którą ujawniłem za pomocą boost.python.

Mam klasę, która jest narażona na python za pomocąstd::shared_ptr. Ta klasa powinna być w stanie podnieść pewne sygnały dotyczące pewnych zdarzeń. Dlatego ujawniłemconnect_slot funkcja, która przyjmujeboost::python::object jako argument. Jeśli podniosę sygnał bezpośrednio po podłączeniu gniazda, wszystko działa dobrze, ale jeśli klasa podniesie sygnały później, otrzymam błędy segmentacji.

Myślę, że może to mieć coś wspólnego z wątkami w lib c ++ (używa również boos :: asio itp.)

Oto kilka fragmentów kodu:

MyClass.h:

public:
    typedef boost::signals2::signal<void (std::shared_ptr<int>)> signal_my_sig;
    void connect_slot(boost::python::object const & slot);

private:
    signal_my_sig    m_sig;

MyClass.cpp:

void MyClass::connect_slot(boost::python::object const & slot) { 
    std::cout << "register shd" << std::endl;
    m_sig.connect(slot);

    m_sig(12345); // this works
}


void MyClass::some_later_event() {
    m_sig(654321); // this does not work

}

Wywołuję funkcję MyClass :: connect_slot w pythonie z niestandardową funkcją pythona w następujący sposób:

def testfunc(some_int):
    print("slot called")

m = myext.MyClass()
m.connect_slot(testfunc)

Backtrace (przy użyciu gdb) błędu segmentacji, który został podniesiony wMyClass::some_later_event wygląda tak:

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff3c37700 (LWP 20634)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff3c37700 (LWP 20634)]
0x00000000004f7480 in PyObject_Call ()
(gdb) 
(gdb) backtrace
#0  0x00000000004f7480 in PyObject_Call ()
#1  0x00000000004f7aa6 in PyEval_CallObjectWithKeywords ()
#2  0x000000000049bd84 in PyEval_CallFunction ()
#3  0x00007ffff5375d9f in boost::python::call<boost::python::api::object, int>
(callable=0x7ffff7ed4578, a0=@0x7ffff3c35b34: 5)
at /usr/local/boost_1_55_0/boost/python/call.hpp:66
#4  0x00007ffff5374b81 in boost::python::api::object_operators<boost::python::api::object>::operator()<int> (this=0x9e3bf0, a0=@0x7ffff3c35b34: 5)
at /usr/local/boost_1_55_0/boost/python/object_call.hpp:19
#5  0x00007ffff5373658 in boost::detail::function::void_function_obj_invoker1<boost::python::api::object, void, int>::invoke (function_obj_ptr=..., a0=5)
at /usr/local/boost_1_55_0/boost/function/function_template.hpp:153
#6  0x00007ffff5378a3c in boost::function1<void, int>::operator() (
this=0x9e3be8, a0=5)
at /usr/local/boost_1_55_0/boost/function/function_template.hpp:767
#7  0x00007ffff53781f9 in boost::signals2::detail::call_with_tuple_args<boost::signals2::detail::void_type>::m_invoke<boost::function<void (int)>, 0u, int&>(void*, boost::function<void (int)>&, boost::signals2::detail::unsigned_meta_array<0u>, std::tuple<int&>) const (this=0x7ffff3c35c7f, func=..., args=...)
at /usr/local/boost_1_55_0/boost/signals2/detail/variadic_slot_invoker.hpp:92

Jakieś pomysły?

questionAnswers(2)

yourAnswerToTheQuestion