Robotics StackExchange | Archived questions

link c code with c++ ROS code

I am having trouble with linking c-code with C++-code. The C++ code describes a ROS-node. I made a program that can read a compressed image-stream over udp with gstreamer in c-code. Each image-buffer calls a C++-method of the ROS-node, which effectively converts the gstreamer stream into a ROS image stream.

I organised it as such:

  1. udptoros3.c file that describes gstreamer-functionality,
  2. ros_cpp.cpp file with class and wrapper for C-code to indirectly call class
  3. roscpp.o.so dynamic library compiled by catkinmake from roscpp.cpp (location: /home/edward/catkinws/devel/lib/)
  4. imimageconv.h header of wrapper-code, used in roscpp.cpp and updtoros3.c

I compiled updtoros3.c to updtoros3.o, and roscpp.o.so is compiled by catkinmake.

Now try to link it with: gcc -Wall -L/home/edward/catkinws/devel/lib/ udptoros3.o -lroscpp.o $(pkg-config --cflags --libs gstreamer-0.10) -lgstapp-0.10 -o udptoros_image

I get the following errors:

/home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to cv::fastFree(void*)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toros::init(int&, char**, std::basicstring<char, std::chartraits, std::allocator > const&, unsigned int)' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to ros::NodeHandle::~NodeHandle()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toimagetransport::ImageTransport::ImageTransport(ros::NodeHandle const&)' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to `ros::Time::now()' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to `imagetransport::Publisher::publish(boost::sharedptr<sensormsgs::Imagestd::allocator<void > const> const&) const' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to `imagetransport::ImageTransport::~ImageTransport()' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to ros::NodeHandle::NodeHandle(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference tocv::waitKey(int)' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to cv_bridge::CvImage::toImageMsg() const' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toros::spinOnce()' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to cv::Mat::copySize(cv::Mat const&)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference tocv::Mat::deallocate()' /home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to `imagetransport::ImageTransport::advertise(std::basicstring, std::allocator > const&, unsigned int, bool)' collect2: ld returned 1 exit status

I think it needs the ROS-headerfiles, but maybe also the libraries (?) as used by catkin to be able to link the two files. But even when I add -I/opt/ros/groovy/include/ros/ it still complains about undefined reference to ros:: things.

How to solve this the most pragmatic? Do I need to compile also the C-file within catkin CMakefile and link them together, or is there another way ?

Asked by edward on 2013-12-31 01:37:52 UTC

Comments

Answers

To answer your last question, you do not necessarily need to compile your standalone (in the sense of ROS independent) c code within catkin. It is pretty straight forward to compile your c code as a shared or static library, and then link your ROS node to it using the standard CMake syntax (by adding your c library to target_link_libraries(...) for example).

To address your linker errors. You are not missing header files, you are improperly specify the libraries to link to and the library search paths. Remember that "-L" specifies the search path, and the "-l" specifies the library name (preferably without path and without ending). For object files ".o" you do not need the "-l" flag prefix. you are missing lots of opencv libraries in command, you can try adding "-lopencv_core" and "-lcv_bridge -limage_transport" to take care of the missing OpenCV and OpenCV binding symbols.

But I highly recommend you use the cakin for building and integrating your ROS code, and not to build things by hand.

EDIT: Responding to your further comments, you are using the CMake commands incorrectly. To create your library and link to it in CMake you should use:

add_library(upd_to_ros SHARED src/upd_to_ros3.cpp) #add the source files for your "external" library code here
add_executable(imageconv_node src/ros_cpp.cpp )
target_link_libraries(imageconv_node 
    upd_to_ros
    ${catkin_LIBRARIES} 
)

Note that your ROS node imageconv_node declared in your CMakeLists.txt will need a typical main function, and it is bad practice to hard code full paths in a CMakeLists.txt.

Asked by jensenb on 2013-12-31 05:30:31 UTC

Comments

I also tried it by hand , compiled : gcc -Wall upd_to_ros3.o -o udp_to_ros_image -L/home/edward/catkin_ws/devel/lib/ -lros_cpp.o $(pkg-config --cflags --libs gstreamer-0.10) -lgstapp-0.10 -lopencv_core -L/opt/ros/groovy/lib/ -lrostime -limage_transport -lcv_bridge -lopencv_highgui

This was successful.

Asked by edward on 2013-12-31 11:57:48 UTC

Thank you for your answer Jensenb. In the catkin CMakeList.txt I declared the following:

add_executable(imageconv_node src/ros_cpp.cpp ) <-- which is really the library (it has no main)
target_link_libraries(
/home/edward/c920/upd_to_ros3.o
<-- compiled before
${catkin_LIBRARIES}
)

Then get the following error:

CMake Error at CMakeLists.txt:115 (target_link_libraries): Cannot specify link libraries for target "/home/edward/c920/upd_to_ros3.o" which is not built by this project.

How to continue?

Asked by edward on 2013-12-31 11:23:21 UTC

Comments

Please do not answers to your question that are not answers but further questions. Instead either edit your original question, or post a comment to my answer. You should delete this post.

Asked by jensenb on 2014-01-01 00:46:58 UTC