Robotics StackExchange | Archived questions

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 catkinws/devel/lib/python2.7/dist-packages/wrapper-pkg/guidanceext.so as expected.

I've determined the following: guidanceext.so (the python wrapper library) links to libguidancefactory.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.

Asked by Nathan Powel on 2015-03-14 00:23:44 UTC

Comments

rqt also accepts plugins written directly in Python. That might be simpler and easier to maintain.

Asked by joq on 2015-03-14 10:57:35 UTC

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.

Asked by Nathan Powel on 2015-03-14 13:16:40 UTC

Make sure you don't call find_package(catkin REQUIRED COMPONENTS ....) more than once other wise the catkin_LIBRARIES variable will not contain what you think. You can also message(..) out the value of catkin_LIBRARIES to ensue it contains the libroscpp.so entry.

Asked by William on 2015-03-14 18:14:02 UTC

Rqt also works with CPP plugins. Then you don't have to deal with bindings at all.

Asked by Dirk Thomas on 2015-03-14 20:34:06 UTC

@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.

Asked by Nathan Powel on 2015-03-14 21:43:13 UTC

@William I added message(catkin_LIBRARIES) in my build file and libroscpp.so was listed. But if I ldd guidance_ext.so (my Python module) libroscpp.so isn't listed. I don't have two calls to find_package(catkin REQUIRED ...).

Asked by Nathan Powel on 2015-03-14 21:45:38 UTC

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 in catkin_package of CMakelists.txt

Asked by Wolf on 2015-03-16 08:36:18 UTC

I guess that would make the guidance_factory in target_link_libraries(guidance_ext guidance_factory ${catkin_LIBRARIES} ${Boost_LIBRARIES} ) obsolete??

Asked by Wolf on 2015-03-16 08:37:04 UTC

@Wolf The package containing guidance_factory is listed in my find_package(...). I was just trying to balance precision and concision in my original post. The guidance_factory library is exported from that package. Not sure why that makes the link obsolete though.

Asked by Nathan Powel on 2015-03-16 09:19:30 UTC

Answers

I ended up fixing this by making sure to link libGuidance.so to ${catkin_LIBRARIES}. I thought it already had been, but a second look revealed otherwise. Why this never bit me before, I'm not sure.

So to sum up: the problem was a missing link on a library (Guidance) that the library I was wrapping (guidance_factory) was linking to.

Thanks all, for your responses.

Asked by Nathan Powel on 2015-03-17 13:20:18 UTC

Comments