0

I've been trying to compile my project and I've encountered some problems when trying so. The error in particular that appears is:

[build] /usr/bin/ld: CMakeFiles/robot_control.dir/main.cpp.o:(.data.rel.ro._ZTVN4comm15cameraInterfaceE[_ZTVN4comm15cameraInterfaceE]+0x10): undefined reference to `comm::Interface<cv::Mat>::callbackMsg()'

My project is organized right now as it follows:

-${HOME_WORKSPACE}
 |-main.cpp 
 |-src
   |-communication.cpp
   |-communication.hpp

The header file (communication.hpp) is:

#include <opencv2/opencv.hpp>
#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <algorithm>

#ifndef COMM_GUARD
#define COMM_GUARD

namespace comm
{
    struct lidarMsg
    {
        float angle_min, angle_increment, range_min, range_max;
        int nranges, nintensities;
        std::vector<int> ranges;
    };

    template <typename T>
    class Interface
    {
        public:
            Interface() : received{false} {};

            virtual void callbackMsg();

            bool receptionAccomplished()
            {
                return this -> received;
            }
            
            T checkReceived()
            {
                return this -> elementReceived;
            }
        
        protected:
            bool received;
            T elementReceived;

    };

    class cameraInterface : public Interface<cv::Mat>
    {
        public:
            void callbackMsg(ConstImageStampedPtr &msg);
    };

    class lidarInterface : public Interface<lidarMsg>
    {
        public:
            void callbackMsg(ConstLaserScanStampedPtr &msg);
    };
}

#endif

The source file (communication.cpp) is:

#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
#include "communication.hpp"

#ifndef COMM_CPP_GUARD
#define COMM_CPP_GUARD

namespace comm
{

    void cameraInterface::callbackMsg(ConstImageStampedPtr &msg)
    {
        std::size_t width = msg->image().width();
        std::size_t height = msg->image().height();
        const char *data = msg->image().data().c_str();
        cv::Mat im(int(height), int(width), CV_8UC3, const_cast<char *>(data));
        im = im.clone();
        cv::cvtColor(im, im, cv::COLOR_RGB2BGR);

        this->elementReceived = im;
        received = true;
    }

    void lidarInterface::callbackMsg(ConstLaserScanStampedPtr &msg) {

        this->elementReceived.angle_min = float(msg->scan().angle_min());
        this->elementReceived.angle_increment = float(msg->scan().angle_step());
        this->elementReceived.range_min = float(msg->scan().range_min());
        this->elementReceived.range_max = float(msg->scan().range_max());
        this->elementReceived.nranges = msg->scan().ranges_size();
        this->elementReceived.nintensities = msg->scan().intensities_size();

        for (int i = 0; i < this->elementReceived.nranges; i++)
        {
            if (this->elementReceived.ranges.size() <= i)
            {
                this->elementReceived.ranges.push_back(std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max));
            }
            else
            {
                this->elementReceived.ranges[i] = std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max);
            }
        }
    }
}

#endif

The main file(main.cpp) includes the following header:

#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
#include <stdlib.h>

#include "src/communication.hpp"

I included the part of the #ifndef /#define /#endif since it is a solution that I found to this kind of problem in other problem. I've been toggling the CMakeLists.txt file but still no solution that could solve this error.

  • Unrelated: [The best use of a gazebo, ever.](https://www.youtube.com/watch?v=FoTTLusJ8mU) – user4581301 Oct 27 '21 at 18:36
  • 2
    Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Richard Critten Oct 27 '21 at 19:40

1 Answers1

1

You can't do this:

        virtual void callbackMsg();

You have to actually provide the implementation for all template methods within the .h file.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36