Reputation: 4716
I am in the middle of porting code from Visual Studio to Mingw GCC. This component works fine in Visual studio however Mingw GCC complains about a undefined reference to a function. I have isolated the situation and am putting down the code here
File : Rng.h
#pragma once
#ifdef RNG_EXPORTS
#define RNG_API __declspec(dllexport)
#else
#define RNG_API __declspec(dllimport)
#endif
RNG_API unsigned long GetRandom(unsigned long range);
File : Rng.cpp
#include "Rng.h"
#include "RngKiss.h"
static TRngFile gRngFile;
unsigned long GetRandom(unsigned long range)
{
gRngFile.generate_rnd(); //Linker Error : Undefined Reference to function.
....
}
File: RngKiss.h
#ifndef __RNGKISS_H__
#define __RNGKISS_H__
#ifndef ULONG
typedef unsigned long ULONG;
#endif //ULONG
typedef struct
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
#endif
File : RngKiss.cpp
#include "RngKiss.h"
ULONG TRngFile::generate_rnd(void)
{
ULONG d;
return d;
}
This is my output.
g++.exe -L..\..\..\mingw64\lib\boost -o bin\Debug\TestCodeBlocks.exe obj\Debug\main.o obj\Debug\Rng.o obj\Debug\RngKiss.o
obj\Debug\Rng.o: In function `GetRandom(unsigned long)':
C:/Users/admin/TestCodeBlocks/Rng.cpp:8: undefined reference to `TRngFile::generate_rnd()'
collect2.exe: error: ld returned 1 exit status
Any suggestions on why I am getting this linker error and how i can resolve it ?
Upvotes: 1
Views: 1523
Reputation: 61590
You have fallen foul of a bug (or at least an eccentricity) in your mingw64
compiler, in the rather obscure matter of
compiling unnamed structs. I don't know what version you have, but my mingw32
4.8.1
has the same behaviour:
These typedef
s in rngKiss.h
:-
typedef struct
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
You may think that they respectively define a struct
type called TRngRecord
and another called
TRngFile
, but strictly they define TRngRecord
and TRngFile
to be aliases of struct
types
which themselves are unnamed.
The difference should be merely conceptual. So it is for Microsoft's compiler and for TDM GCC 4.9.2 on Windows, and so it is for GCC 4.9.2 and clang 3.5.1 on Linux.
Our mingw
compilers, however, appear to hold that members of the unamed struct
typedefed as
TRngFile
must have static linkage. Mine generates:
Dump of file rngKiss.o
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 00000000 DEBUG notype Filename | .file
rngKiss.cpp
002 00000000 SECT1 notype () Static | __ZN8TRngFile12generate_rndEv
...
Hence the linkage error. Whereas TDM GCC 4.9.2 generates:
Dump of file rngKiss.o
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 00000000 DEBUG notype Filename | .file
rngKiss.cpp
002 00000000 SECT1 notype () External | _ZN8TRngFile12generate_rndEv
...
There are 3 solutions for this:
Change your compiler, say to TDM GCC.
Give names to your typedefed struct
s:
typedef struct TRngRecord
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
or best of all:
Drop the typedef
s, which are a strange and unnecessary way of naming classes in C++:
struct TRngRecord
{
ULONG w, x, y, z;
};
struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
};
....
#include "rngKiss.h"
...
static TRngFile gRngFile;
Upvotes: 3
Reputation: 16540
the question states that the function is in a library.
this indicates the linker statement is missing either the '-Lpath to the library directory' and/or '-ltruncated libary name'
Upvotes: 0
Reputation: 16540
a few ideas come to mind.
1) the '::' scope operator is most often used to access a method of a class.
(another common use is to reference a function in a namespace)
However, I do not see any class definition header file.
(normally, the class header file is the same name as the class)
2) there has to be a prototype in a class header file
(usually this is part of the class declaration/interface)
for the generate_rnd() method.
So, where is the class header?
So, where is the method prototype?
Upvotes: 0