0

I have a function to convert from one image representation (MyImage) to a QImage, and I decided it would be tidier to dedicate a namespace to functions that interface in this manner. I previously had this function directly in the class representing my main QMainWindow.

So, I created a file MyFormatToQtInterfacing.h which looks as follows:

#include <QtGui/QMainWindow>
#include <qlabel.h>

namespace MyFormatToQtInterfacing
{
    // These functions below convert a cv::Mat to a QImage.
    // Adapted from http://stackoverflow.com/questions/5026965/how-to-convert-an-opencv-cvmat-to-qimage
    // The grayscale ones seem to be inverted.  Look into this later.

    QImage MyImage2QImage(const MyImage &src) { //snip };
};

I then call the function from this new namespace, as you would expect, and I get the following linker error:

1>main.obj : error LNK2005: "class QImage _cdecl MyFormatToQtInterfacing::Mat2QImage(class MyImage2QImage const &)" (?MyImage2QImage@MyFormatToQtInterfacing@@YA?AVQImage@@ABV?$Mat@V?$Vec@E$02@cv@@@cv@@@Z) already defined in moc_Tracker.obj

1>Tracker.obj : error LNK2005: "class QImage _cdecl MyFormatToQtInterfacing::MyImage2QImage(class MyImage2QImage const &)" (?MyImage2QImage@MyFormatToQtInterfacing@@YA?AVQImage@@ABV?$Mat@V?$Vec@E$02@cv@@@cv@@@Z) already defined in moc_Tracker.obj

1>C:\Projects\Tracker\Tracker.exe : fatal error LNK1169: one or more multiply defined symbols found

I've also been subbing out MyImage with OpenCV matrices and getting the same problem. Why is this happening and how can I resolve it?

zebra
  • 6,373
  • 20
  • 58
  • 67

3 Answers3

1

If you define the function in the header, you must also make it inline to avoid this problem.

 inline QImage MyImage2QImage(const MyImage &src) { /*snip*/ };
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

You should add a header guard, and in addition make the function inline if you define the function in the header.

#ifndef MYIMAGE2QIMAGE_H
#define MYIMAGE2QIMAGE_H

inline QImage MyImage2QImage(const MyImage &src) { //snip };

#endif // MYIMAGE2QIMAGE_H
James Custer
  • 857
  • 6
  • 12
1

You are falling afoul of the one definition rule. You are not allowed to define non inline or non template functions in headers that are included in multiple compilation units. Move your definition to a .cpp file or mark the function as inline.

rerun
  • 25,014
  • 6
  • 48
  • 78
  • Thanks for this. I didn't know that. How would I know whether it is a better idea to make the function inline, or to make a whole separate .cpp file? – zebra May 01 '12 at 18:33