首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++链接错误:编译器找不到函数的定义

C++链接错误:编译器找不到函数的定义
EN

Stack Overflow用户
提问于 2011-12-05 15:20:14
回答 3查看 1.7K关注 0票数 0

我有一个文件Cache.cpp,它有一个对应的头文件Cache.h和另一个NetFunctions.cpp,它有一个对应的头文件NetFunction.h。

我有一个makefile,看起来像这样

代码语言:javascript
运行
复制
all: net cache
    g++ main.cpp ../obj/NetFunctions.o ../obj/Cache.o -o ../bin/main
net: NetFunctions.cpp
    g++ -c NetFunctions.cpp -o ../obj/NetFunctions.o
cache: Cache.cpp net
    g++ -c Cache.cpp ../obj/NetFunctions.o -o ../obj/Cache.o

现在NetFunctions.cpp在其中定义了一个函数getNFHTML(string),该函数在Cache.cpp中使用。我已经检查了头文件,它们看起来很好,所有的函数,声明在那里和头文件适当地包括在内。

然而,当我这样做时,我得到了下面的链接器错误

代码语言:javascript
运行
复制
../obj/Cache.o: In function `Cache::getHTML(std::basic_string<char,  std::char_traits<char>, std::allocator<char> >)':
Cache.cpp:(.text+0x19ee): undefined reference to `getNFHTML(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status
make: *** [test] Error 1***

有人能帮我一下吗?有什么问题吗?

我也参考了这个帖子C++ Linking error,但它对我没有帮助。

编辑

代码如下: NetFunctions.h

代码语言:javascript
运行
复制
#ifndef NET
#define NET 1

#include "commons.h"

bool serv_bind(struct addrinfo **servinfo, struct addrinfo **p, int *sockfd, int *yes);
void* get_in_addr(struct sockaddr *sa);
string getNFHTML(string website);  
string saveHeaders(string);
//bool getNFHTML(string request, string last_modified, string *response);
extern bool useCache;

#endif

NetFunctions.cpp

代码语言:javascript
运行
复制
    #include "NetFunctions.h"
    string getNFHTML(string request)
    {
    // a lot of code
    }

Cache.cpp

代码语言:javascript
运行
复制
#include "NetFunctions.h"
#include "Cache.h"
string Cache::getHTML(string request)
{
//some code
    string response = getNFHTML(request);
//some code
}

我已经去掉了文件,因为它们包含数百行

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-05 15:36:34

这与问题无关,但我把它放在一个答案中,这样它就会更好地格式化。

您的makefile不能很好地处理依赖关系。试试这个吧:

代码语言:javascript
运行
复制
.PHONY: all
all: ../bin/main

../bin/main: main.cpp ../obj/NetFunctions.o ../obj/Cache.o
    g++ $^ -o $@

../obj/NetFunctions.o: NetFunctions.cpp
    g++ -c $< -o $@

../obj/Cache.o: Cache.cpp 
    g++ -c $< -o $@

对于../bin/main目标,变量$^表示接受所有先决条件,而$@是规则的目标。这意味着您可以添加任意数量的对象文件,并且所有对象文件都将被链接。

对于将源文件编译为目标文件,$<变量是第一个先决条件。如果您添加更多的文件,这也将使复制/粘贴目标变得更容易。

这些规则还确保在构建../bin/main时,它所依赖的所有文件都将正确构建。

如果在不指定目标的情况下运行make,则第一个目标all将是默认目标。它被标记为假目标,因为它不会生成一个名为all的文件。

请注意,我基于GNU make,它是几乎所有Linux发行版和Cygwin/MingW中的标准。如果你使用BSD make,变量可能会改变。

票数 1
EN

Stack Overflow用户

发布于 2011-12-05 15:27:52

更改:

代码语言:javascript
运行
复制
cache: Cache.cpp net
    g++ -c Cache.cpp ../obj/NetFunctions.o -o ../obj/Cache.o

至:

代码语言:javascript
运行
复制
cache: Cache.cpp net
    g++ -c Cache.cpp -o ../obj/Cache.o

更好的是,去掉虚拟目标,打开编译器警告:

代码语言:javascript
运行
复制
../bin/main: ../obj/NetFunctions.o ../obj/Cache.o
    g++ -Wall main.cpp ../obj/NetFunctions.o ../obj/Cache.o -o $@
../obj/NetFunctions.o: NetFunctions.cpp
    g++ -Wall -c NetFunctions.cpp -o $@
../obj/Cache.o: Cache.cpp
    g++ -Wall -c Cache.cpp -o $@
票数 0
EN

Stack Overflow用户

发布于 2011-12-05 15:31:59

虽然你的Makefile已经坏了,但是很明显,如果你说的是的话,是不是这样的:

NetFunctions.cpp在其中定义了函数getNFHTML(字符串

是真的,那么它就会起作用。因此,这一定是你在对我们撒谎。在NetFunctions.cpp中显示getNFHTML的代码,或者至少显示以下内容的输出:

代码语言:javascript
运行
复制
nm ../obj/NetFunctions.o | grep getNFHTML

更新:

好吧,你告诉我们的都是真的。但是,看起来链接失败的目标名为test,并且您的makefile中没有这样的目标。

我猜测该目标是在链接线上没有所需NetFunctions.o的情况下链接的。

在任何情况下,请使用失败的实际链接行更新您的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8382099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档