ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

link c code with c++ ROS code

asked 2013-12-31 00:37:52 -0600

updated 2013-12-31 23:49:27 -0600

jensenb gravatar image

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. udp_to_ros3.c file that describes gstreamer-functionality,
  2. ros_cpp.cpp file with class and wrapper for C-code to indirectly call class
  3. ros_cpp.o.so dynamic library compiled by catkin_make from ros_cpp.cpp (location: /home/edward/catkin_ws/devel/lib/)
  4. im_imageconv.h header of wrapper-code, used in ros_cpp.cpp and upd_to_ros3.c

I compiled upd_to_ros3.c to upd_to_ros3.o, and ros_cpp.o.so is compiled by catkin_make.

Now try to link it with: gcc -Wall -L/home/edward/catkin_ws/devel/lib/ udp_to_ros3.o -lros_cpp.o $(pkg-config --cflags --libs gstreamer-0.10) -lgstapp-0.10 -o udp_to_ros_image

I get the following errors:

/home/edward/catkin_ws/devel/lib//libros_cpp.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::basic_string<char, std::char_traits<char="">, std::allocator<char> > const&, unsigned int)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to ros::NodeHandle::~NodeHandle()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toimage_transport::ImageTransport::ImageTransport(ros::NodeHandle const&)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to ros::Time::now()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toimage_transport::Publisher::publish(boost::shared_ptr<sensor_msgs::image_<std::allocator<void> > const> const&) const' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to image_transport::ImageTransport::~ImageTransport()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toros::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/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference tocv_bridge::CvImage::toImageMsg() const' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to ros::spinOnce()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference tocv::Mat::copySize(cv::Mat const&)' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference to cv::Mat::deallocate()' /home/edward/catkin_ws/devel/lib//libros_cpp.o.so: undefined reference toimage_transport::ImageTransport::advertise(std::basic_string<char, std::char_traits<char="">, std::allocator<char> > 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 ... (more)

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2013-12-31 10:23:21 -0600

updated 2013-12-31 10:24:26 -0600

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?

edit flag offensive delete link more

Comments

2

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.

jensenb gravatar image jensenb  ( 2013-12-31 23:46:58 -0600 )edit
0

answered 2013-12-31 04:30:31 -0600

jensenb gravatar image

updated 2013-12-31 23:44:32 -0600

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.

edit flag offensive delete link more

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.

edward gravatar image edward  ( 2013-12-31 10:57:48 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-12-31 00:37:52 -0600

Seen: 2,765 times

Last updated: Dec 31 '13