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:
- udptoros3.c file that describes gstreamer-functionality,
- ros_cpp.cpp file with class and wrapper for C-code to indirectly call class
- roscpp.o.so dynamic library compiled by catkinmake from roscpp.cpp (location: /home/edward/catkinws/devel/lib/)
- 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 to
ros::init(int&, char**, std::basicstring<char, std::chartraitsros::NodeHandle::~NodeHandle()'
/home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to
imagetransport::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 to
cv::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 to
ros::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 to
cv::Mat::deallocate()'
/home/edward/catkinws/devel/lib//libroscpp.o.so: undefined reference to `imagetransport::ImageTransport::advertise(std::basicstring
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
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(
<-- compiled before
/home/edward/c920/upd_to_ros3.o
${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
Comments