Using C++ streams to serialize numbers crashes boost.python on the Mac
I think something is wrong with my linking (I am running on a mac, and had to change the library to be a MODULE?). Here's what I have:
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
project (testme)
FIND_PACKAGE( Boost REQUIRED )
FIND_PACKAGE( Boost COMPONENTS python REQUIRED )
FIND_PACKAGE( PythonLibs REQUIRED )
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREAD ON)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${PYTHON_INCLUDE_PATH})
add_library(testme MODULE tutorial.cpp)
target_link_libraries(testme ${PYTHON_LIBRARY} ${Boost_PYTHON_LIBRARY})
tutorial.cpp
#include <boost/python.hpp>
struct TestClass { TestClass() {} };
std::ostream &operator<<(std::ostream &ostr, const TestClass &ts)
{
ostr << 1 << "\n";
return ostr;
}
BOOST_PYTHON_MODULE(libtestme)
{
using namespace boost::python;
class_<TestClass>("TestClass", init<>())
.def(self_ns::str(self))
;
}
a.py
#!/usr/bin/env python
import libtestme as d
a = d.TestClass()
print a
Running a.py crashes unless ostr << 1 << "\n";
is commented out or replaced with ostr << "1" << "\n";
!
Build and run:
cmake .
make
./a.py
Stack trace (after doing gdb --args python a.py
):
#0 0x00007fff817003d6 in __kill ()
#1 0x00007fff817a0972 in abort ()
#2 0x000000010069baf2 in uw_init_context_1 ()
#3 0x000000010069bf38 in _Unwind_Resume ()
#4 0x00000001004a1283 in boost::detail::lexical_cast<std::string, TestClass, true, char> (arg=@0x100343a70, buf=开发者_如何学C0x7fff5fbfe307 "", src_len=0) at lexical_cast.hpp:1153
#5 0x00000001004a0db4 in boost::lexical_cast<std::string, TestClass> (arg=@0x100343a70) at lexical_cast.hpp:1174
#6 0x00000001004a0b64 in boost::python::detail::operator_1<(boost::python::detail::operator_id)19>::apply<TestClass>::execute (x=@0x100343a70) at operators.hpp:357
#7 0x00000001004a4417 in boost::python::detail::invoke<boost::python::to_python_value<_object* const&>, _object* (*)(TestClass&), boost::python::arg_from_python<TestClass&> > (rc=@0x7fff5fbfe406, f=@0x10033e318, ac0=@0x7fff5fbfe3f0) at invoke.hpp:75
#8 0x00000001004a3fb1 in boost::python::detail::caller_arity<1u>::impl<_object* (*)(TestClass&), boost::python::default_call_policies, boost::mpl::vector2<_object*, TestClass&> >::operator() (this=0x10033e318, args_=0x100452a10) at caller.hpp:223
#9 0x00000001004a3ba7 in boost::python::objects::caller_py_function_impl<boost::python::detail::caller<_object* (*)(TestClass&), boost::python::default_call_policies, boost::mpl::vector2<_object*, TestClass&> > >::operator() (this=0x10033e310, args=0x100452a10, kw=0x0) at py_function.hpp:38
#10 0x000000010061797a in boost::python::objects::function::call ()
#11 0x0000000100617d10 in boost::detail::function::void_function_ref_invoker0<boost::python::objects::(anonymous namespace)::bind_return, void>::invoke ()
#12 0x000000010061f431 in boost::python::handle_exception_impl ()
#13 0x0000000100614b5e in function_call ()
#14 0x000000010000c4a2 in PyObject_Call ()
#15 0x000000010001e8bd in instancemethod_call ()
#16 0x000000010000c4a2 in PyObject_Call ()
#17 0x00000001000ba2f7 in PyEval_CallObjectWithKeywords ()
#18 0x0000000100077c0a in slot_tp_str ()
#19 0x000000010005aafa in _PyObject_Str ()
#20 0x000000010005b0dd in internal_print ()
#21 0x0000000100032ccd in PyFile_WriteObject ()
#22 0x00000001000bf09b in PyEval_EvalFrameEx ()
#23 0x00000001000c2936 in PyEval_EvalCodeEx ()
#24 0x00000001000c2a56 in PyEval_EvalCode ()
#25 0x00000001000e744e in PyRun_FileExFlags ()
#26 0x00000001000e7709 in PyRun_SimpleFileExFlags ()
#27 0x00000001000fde8c in Py_Main ()
#28 0x0000000100000f14 in dyld_stub_strlen ()
In the example above the constructor call needs to be:
a= d.TestClass()
otherwise the example works fine on Ubuntu 10.04LTS with gcc 4.4.3 and boost 1.40
精彩评论