简体   繁体   中英

Boost, ros and catkin - linker error

I have installed Boost libraries on Ubuntu 14.04, and I'm trying to build a ros package in a catkin workspace. The package is a system for a drone's autonomous navigation composed of three components: one of these allows to create a 3D map of cloud points. My target is to modify this package, in order to save and load the cloud points that I get.

I thought to use Boost libraries to serialize the data structure containing the 3D map.

This is my map's data structure (with the serialize function added by me):

#include <vector>
#include <TooN/se3.h>
#include <cvd/image.h>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

struct MapPoint;
struct KeyFrame;

struct Map
{
  Map();
  inline bool IsGood() {return bGood;}
  void Reset();

  void MoveBadPointsToTrash();
  void EmptyTrash();

  template<class Archive>
  void serialize(Archive & ar, const unsigned int version);

  std::vector<MapPoint*> vpPoints;
  std::vector<MapPoint*> vpPointsTrash;
  std::vector<KeyFrame*> vpKeyFrames;

  bool bGood;
};

And this is my implementation of the function serialize:

template<class Archive>
void Map::serialize(Archive & ar, const unsigned int version) {
    ar & vpPoints;
    ar & vpPointsTrash;
    ar & vpKeyFrames;
}

The serialization is called by another file (PTAMwrapper.cpp) that handle the command on a ros topic:

//..
Map *mpMap; 
//..

bool PTAMWrapper::handleCommand(std::string s)
    {
        if(s.length() == 4 && s.substr(0,4) == "save")
            {
                //save into file
                const char *path="/home/user/Desktop/aGreatMap";
                std::ofstream file(path); //open in constructor
                // save data to archive
                {
                    Map tMap = *mpMap;
                    boost::archive::text_oarchive oa(file);
                    // write class instance to archive
                    oa << tMap;
                    // archive and stream closed when destructors are called
                }
            }

    //...

When I issue catkin_make , operation failed, giving me error:

Linking CXX executable /home/user/catkin_ws/devel/lib/tum_ardrone/drone_stateestimation
CMakeFiles/drone_stateestimation.dir/src/stateestimation/PTAMWrapper.cpp.o: in function "serialize<boost::archive::text_oarchive, Map>":
/usr/local/include/boost/serialization/access.hpp:116: undefined reference to "void Map::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive&, unsigned int)"
CMakeFiles/drone_stateestimation.dir/src/stateestimation/PTAMWrapper.cpp.o: in function "void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&)":
/usr/local/include/boost/serialization/throw_exception.hpp:36: undefined reference to "boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)"
collect2: error: ld returned 1 exit status
make[2]: *** [/home/user/catkin_ws/devel/lib/tum_ardrone/drone_stateestimation] Error 1
make[1]: *** [tum_ardrone/CMakeFiles/drone_stateestimation.dir/all] Error 2
make: *** [all] Error 2
Invoking "make -j4 -l4" failed

I thought that is a linking problem. It is right? Any suggestions to solve it?


EDIT: this is my CMakeLists.txt file:

//...
find_package(catkin REQUIRED COMPONENTS
  ardrone_autonomy
  cv_bridge
  dynamic_reconfigure
  geometry_msgs
  sensor_msgs
  std_msgs
  std_srvs
  message_generation
  roscpp
  rospy
)

find_package(Boost COMPONENTS serialization REQUIRED)

//...

add_executable(drone_stateestimation ${STATEESTIMATION_SOURCE_FILES} ${STATEESTIMATION_HEADER_FILES})
set_target_properties(drone_stateestimation PROPERTIES COMPILE_FLAGS "-D_LINUX -D_REENTRANT -Wall  -O3 -march=nocona -msse3") 
target_link_libraries(drone_stateestimation ${PTAM_LIBRARIES} ${catkin_LIBRARIES} ${Boost_SERIALIZATION_LIBRARY})
add_dependencies(drone_stateestimation thirdparty ${PROJECT_NAME}_gencpp ${PROJECT_NAME}_gencfg)

//...
add_executable(drone_autopilot ${AUTOPILOT_SOURCE_FILES} ${AUTOPILOT_HEADER_FILES})
target_link_libraries(drone_autopilot ${catkin_LIBRARIES} ${Boost_SERIALIZATION_LIBRARY})
add_dependencies(drone_autopilot thirdparty ${PROJECT_NAME}_gencpp ${PROJECT_NAME}_gencfg)

//...
add_executable(drone_gui ${GUI_SOURCE_FILES} ${GUI_RESOURCE_FILES_CPP} ${GUI_UI_FILES_HPP} ${GUI_HEADER_FILES_HPP})
target_link_libraries(drone_gui ${QT_LIBRARIES} cvd ${catkin_LIBRARIES} ${Boost_SERIALIZATION_LIBRARY})
add_dependencies(drone_gui thirdparty ${PROJECT_NAME}_gencpp ${PROJECT_NAME}_gencfg)

The problem actually lies in your usage of C++. You have the implementation of a template function in a .cpp file.

The following stackoverflow question addresses why this doesn't work: Why can templates only be implemented in the header file?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM