Undefined symbol ros::Publisher::~Publisher with Boost Python
I have some code written in C++ that I want to wrap using Boost Python so that a colleague can use it in an RQT widget. The code is just a few functions in a library and the wrapper code compiles without errors. However, when I try to import the resulting Python module I get:
ImportError: catkin_ws/devel/lib/libGuidance.so:
undefined symbol: _ZN3ros9PublisherD1Ev
which de-mangles to ros::Publisher::~Publisher. I'm confused because none of the functions in the wrapped library (guidance_factory) make any ROS function calls, though they call static methods of a class (Guidance) which has ros::Publisher objects as member variables. The wrapped methods do this without instantiating the class (I didn't wrap the instantiator method of the factory, nor did I wrap the classes) or referencing the Publisher variables directly or indirectly.
I've followed the example at: ROS/Tutorials/Using a C++ class in Python with appropriate name conversions and the wrapper library shows up in catkin_ws/devel/lib/python2.7/dist-packages/wrapper-pkg/guidance_ext.so as expected.
I've determined the following: guidance_ext.so (the python wrapper library) links to libguidance_factory.so (the C++ library being wrapped) which links to libGuidance.so (the parent class of those classes whose static methods are used) as well as all the child class libs. None of these libraries contain the ros::Publisher symbol (expected) or link to libroscpp.so (slightly unexpected). This is apparently not usually a problem because these libraries have only every been run linked from executables/nodes that do link libroscpp.so. My CMakeLists.txt does includes
find_package(catkin REQUIRED COMPONENTS roscpp)
and
target_link_libraries(guidance_ext
guidance_factory
${catkin_LIBRARIES}
${Boost_LIBRARIES}
)
so I would expect roscpp to be linked.
I'm using Indigo on Ubuntu 14.04. The wrapper code is currently in a different package from the library it's wrapping, but the wrapped library is being exported and the wrapper code compiles.
How can I either get the required linkage to work or else convince catkin that I don't need that symbol anyway? Thanks in advance.
rqt also accepts plugins written directly in Python. That might be simpler and easier to maintain.
Yes, that's what I am trying to do. My colleague is trying to write an RQT plugin in Python, but he needs to make function calls to my C++ library (guidance_factory), so I'm trying to wrap my C++ library in Python using Boost Python. It compiles, it just won't load.
Make sure you don't call
find_package(catkin REQUIRED COMPONENTS ....)
more than once other wise thecatkin_LIBRARIES
variable will not contain what you think. You can alsomessage(..)
out the value ofcatkin_LIBRARIES
to ensue it contains thelibroscpp.so
entry.Rqt also works with CPP plugins. Then you don't have to deal with bindings at all.
@Dirk That is a fallback option. My colleague doesn't know C++ though, so if we go that route, I'm the one who has to write it. I see there is now tutorial for writing C++ RQT plugins, which wasn't there when I looked before, so that makes it more possible.
@William I added
message(catkin_LIBRARIES)
in my build file andlibroscpp.so
was listed. But if Ildd guidance_ext.so
(my Python module)libroscpp.so
isn't listed. I don't have two calls tofind_package(catkin REQUIRED ...)
.Does your package that contains the lib also have roscpp as dependency? Also your lib package should typically occur in
find_package(catkin REQUIRED COMPONENTS roscpp)
, too? Moreover it should export the lib and its deps incatkin_package
of CMakelists.txtI guess that would make the guidance_factory in target_link_libraries(guidance_ext guidance_factory ${catkin_LIBRARIES} ${Boost_LIBRARIES} ) obsolete??