在库的情况下对函数的未定义引用
Undefined reference to function in case of a library
我正在将代码从 Visual Studio 移植到 Mingw GCC。该组件在 Visual studio 中运行良好,但 Mingw GCC 抱怨未定义的函数引用。我已经隔离了情况并在此处放下代码
文件: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);
文件: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.
....
}
文件: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
文件:RngKiss.cpp
#include "RngKiss.h"
ULONG TRngFile::generate_rnd(void)
{
ULONG d;
return d;
}
这是我的输出。
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
关于我为什么会收到此链接器错误以及如何解决它的任何建议?
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.
那么,class header 在哪里?
那么,方法原型在哪里?
问题表明函数在库中。
这表示链接器语句缺少“-Lpath to the library directory”and/or“-ltruncated libary name”
您在 mingw64
编译器中遇到了一个错误(或至少是一个怪癖),在相当晦涩的问题上
编译未命名的结构。我不知道你有什么版本,但是我的 mingw32
4.8.1
具有相同的行为:
rngKiss.h
中的这些typedef
:-
typedef struct
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
你可能认为他们分别定义了一个 struct
类型叫做 TRngRecord
和另一个叫做
TRngFile
,但严格来说,它们将 TRngRecord
和 TRngFile
定义为 struct
类型的别名
它们本身是未命名的。
差异应该只是概念上的。所以这是为了
微软的编译器和 for TDM GCC 4.9.2 on Windows, 所以它是 for
Linux.
上的 GCC 4.9.2 和 clang 3.5.1
然而,我们的 mingw
编译器似乎将 unnamed struct
的成员类型定义为
TRngFile
必须有静态链接。我的生成:
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
...
因此出现链接错误。而 TDM GCC 4.9.2 生成:
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
...
有 3 种解决方案:
改变你的编译器,比如 TDM GCC。
为您的类型定义命名 struct
s:
typedef struct TRngRecord
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
或最重要的是:
删除 typedef
s,这是一种在 C++ 中命名 类 的奇怪且不必要的方式:
struct TRngRecord
{
ULONG w, x, y, z;
};
struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
};
....
#include "rngKiss.h"
...
static TRngFile gRngFile;
我正在将代码从 Visual Studio 移植到 Mingw GCC。该组件在 Visual studio 中运行良好,但 Mingw GCC 抱怨未定义的函数引用。我已经隔离了情况并在此处放下代码
文件: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);
文件: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.
....
}
文件: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
文件:RngKiss.cpp
#include "RngKiss.h"
ULONG TRngFile::generate_rnd(void)
{
ULONG d;
return d;
}
这是我的输出。
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
关于我为什么会收到此链接器错误以及如何解决它的任何建议?
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.
那么,class header 在哪里?
那么,方法原型在哪里?
问题表明函数在库中。
这表示链接器语句缺少“-Lpath to the library directory”and/or“-ltruncated libary name”
您在 mingw64
编译器中遇到了一个错误(或至少是一个怪癖),在相当晦涩的问题上
编译未命名的结构。我不知道你有什么版本,但是我的 mingw32
4.8.1
具有相同的行为:
rngKiss.h
中的这些typedef
:-
typedef struct
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
你可能认为他们分别定义了一个 struct
类型叫做 TRngRecord
和另一个叫做
TRngFile
,但严格来说,它们将 TRngRecord
和 TRngFile
定义为 struct
类型的别名
它们本身是未命名的。
差异应该只是概念上的。所以这是为了 微软的编译器和 for TDM GCC 4.9.2 on Windows, 所以它是 for Linux.
上的 GCC 4.9.2 和 clang 3.5.1然而,我们的 mingw
编译器似乎将 unnamed struct
的成员类型定义为
TRngFile
必须有静态链接。我的生成:
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
...
因此出现链接错误。而 TDM GCC 4.9.2 生成:
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
...
有 3 种解决方案:
改变你的编译器,比如 TDM GCC。
为您的类型定义命名 struct
s:
typedef struct TRngRecord
{
ULONG w, x, y, z;
} TRngRecord;
typedef struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
} TRngFile;
或最重要的是:
删除 typedef
s,这是一种在 C++ 中命名 类 的奇怪且不必要的方式:
struct TRngRecord
{
ULONG w, x, y, z;
};
struct TRngFile
{
TRngRecord current, seed;
ULONG generate_rnd(void);
};
....
#include "rngKiss.h"
...
static TRngFile gRngFile;