对于库的未定义的函数引用

时间:2015-03-06 23:47:08

标签: c++ c visual-studio gcc

我正在将代码从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

有关我为什么会收到此链接器错误以及如何解决此问题的任何建议?

3 个答案:

答案 0 :(得分:3)

你在mingw64编译器中犯了一个错误(或者至少是一个怪癖),这个错误很明显 编译未命名的结构。我不知道你有什么版本,但我的mingw32 4.8.1 有相同的行为:

typedef中的这些rngKiss.h: -

typedef struct
{
    ULONG   w, x, y, z;
} TRngRecord;


typedef struct
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
} TRngFile;

您可能认为他们分别定义了一个名为struct的{​​{1}}类型和另一个名为TRngRecord的类型 TRngFile,但严格来说,他们将TRngRecordTRngFile定义为struct类型的别名 这些都是未命名的。

差异应该只是概念上的。所以这是为了 微软的编译器和Windows上的TDM GCC 4.9.2,以及它的用途 Linux上的GCC 4.9.2和clang 3.5.1。

但是,我们的mingw编译器似乎认为 unamed 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
...

有三种解决方案:

更改编译器,比如TDM GCC。

为typedefed struct提供名称:

typedef struct TRngRecord
{
    ULONG   w, x, y, z;
} TRngRecord;


typedef struct TRngFile
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
} TRngFile;

或者最重要的是:

删除typedef,这是在C ++中命名类的一种奇怪且不必要的方式:

struct TRngRecord
{
    ULONG   w, x, y, z;
};

struct  TRngFile
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
}; 

....

#include "rngKiss.h"
...
static  TRngFile                    gRngFile;

答案 1 :(得分:0)

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.

那么,类标题在哪里?

那么,方法原型在哪里?

答案 2 :(得分:0)

问题表明该功能在库中。

这表明链接器语句缺少库目录的' -Lpath。和/或' -ltruncated libary name'