Dynamic casts returns null when library with C++ python extensions is used as a plugin on RHEL5 -
i have library c++ python extensions (c++ calls python in turn calls c++) using boost::python , python libraries (this messy, lot of legacy) when tested standalone works correctly. in particular, dynamic_cast works correctly.
but when library packaged use plugin on rhel5 using gcc 4.1.2 external application, dynamic_cast returns null resulting in application not working expected. on windows (tested vista 64 bit using visual studio 2005 , 2008) works fine. when debugged using ddd instance, able see pointer before casting has right type_name (slightly mangled compiler usual, suppose?). specific debugging tips here of help.
a reinterpret_cast solved problem. while baulked at, @ loss how proceed, esp. since due issues external app. convoluted mess , seems futile, if can here sample code. following c++ snippet creates "smart_handle" queue python commands stored in string "input". string import imports locations , definitions of functions called boost::python::exec(..) in function call py_api::execute_py_command:
boost::shared_ptr<my_base_class> processor(new my_derived_class()); std::map<std::string, smart_handle> context; context.insert(std::make_pair<std::string, smart_handle>("default_queue", make_smart_handle(processor))); const std::string py_command = import + "namesp.dialects.cpython.set_command_queue('default', default_queue)\n" + input; if( !py_api::execute_py_command(py_command, context) ) { return false; }
the make_smart_handle defined as:
template <typename type_t> const smart_handle make_smart_handle(const boost::shared_ptr<type_t>& ptr) { if( !ptr ) { return smart_handle(); } return smart_handle(new detail::smart_handle_weak_impl<type_t>(ptr)); }
the function set_command_queue defined in python __init__.py as:
import func1 import func2 import func3 import func4 command_queue_map = {} def set_command_queue(queue_name, object): command_queue_map[queue_name] = object def get_command_queue(queue_name = 'default'): return command_queue_map[queue_name]
now actual python functions func1, func2, etc. defined in separate python files calls c++ functions defined under namespace "namesp". first line of these c++ functions recover "smart_handle" "queue" by:
boost::shared_ptr<my_base_class> queue = smart_handle_cast<my_base_class>(handle).lock();
it in above function smart_handle_cast dynamic_cast used returns null, when library used plugin in external app. using reinterpret_cast allows work correctly. smart_handle_cast returns const boost::weak_ptr. interested, here defintion of smart_handle_cast<..>() function:
template <typename type_t> const boost::weak_ptr<type_t> smart_handle_cast(const smart_handle& handle, bool throw_if_failure) { if( !handle.is_valid() ) { if( throw_if_failure ) { throw smart_handle::bad_handle("bad handle, attempting access invalid handle"); } //-no throw version returns non-initialized weak pointer return boost::weak_ptr<type_t>(); } //-this line fails @ run time , returns null. const detail::smart_handle_weak_impl<type_t>* casted = dynamic_cast<const detail::smart_handle_weak_impl<type_t>* >(handle.impl()); if( !casted ) { if( throw_if_failure ) { throw smart_handle::bad_handle_cast("bad handle cast, attempting \ convert incorrect pointee type"); } //-no throw version returns non-initialized weak pointer return boost::weak_ptr<type_t>(); } return casted->pointee; }
take @ similar question , gcc faq
if use dlopen explicitly load code shared library, must several things. first, export global symbols executable linking "-e" flag (you have specify "-wl,-e" if invoking linker in usual manner compiler driver, g++). must make external symbols in loaded library available subsequent libraries providing rtld_global flag dlopen. symbol resolution can immediate or lazy.
Comments
Post a Comment