3

即使我在头文件中放置了包含保护,我总是会收到以下错误。

duplicate symbol _Bittorrent in:
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/main.o
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/Handshake.o
duplicate symbol _eight_byte in:
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/main.o
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/Handshake.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这里是 .h 头文件、.c 文件和 main.c

主程序

#include "Handshake.h"
int main(int argc, char** argv)
{
    // some code.
    return 0;
}

握手.h

#ifndef SHT_Handshake_h
#define SHT_Handshake_h

const char    *Bittorrent     =   "BitTorrent protocol";
const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

#endif

握手.c

#include "Handshake.h"


int Send_fisrt_Handshake(download_connection *pPeer, Handshake *necessary_info)
{
    //some statements
    return 1;
}

void Set_Handshake_information(TorrentFile* pArg, Handshake *pYours)
{

    //some statements

}

但是,如果我从头文件中删除全局变量,这些代码编译成功。
我不明白为什么。有人可以解释为什么吗?先感谢您。

4

5 回答 5

9

像这样的线条

const char    *Bittorrent     =   "BitTorrent protocol";
const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

定义这些全局变量,无论该代码是在头文件中还是直接在 .c 中(#include只是标题内容的文本插入)。相反,您应该将定义放在一个源文件中,并更改标题以提供extern声明:

extern const char *Bittorrent;
extern const char *eight_byte;

然后可以编译使用这些变量的所有源代码,但链接器只会使用一次变量。

于 2013-07-11T12:17:36.727 回答
4

因为你在头文件中定义了变量。然后所有包含头文件的源文件都将定义这些变量。

您可以使用关键字声明变量:extern

extern const char    *Bittorrent;
extern const char    eight_byte[8];

然后在一个源文件中定义变量。

或者您可以将变量定义为static,这将它们的范围限制为翻译单元(即源文件):

static const char    *Bittorrent     =   "BitTorrent protocol";
static const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

这与 C++ 不同,其中const也暗示static.

于 2013-07-11T12:19:50.027 回答
1

标题:

extern const char    *Bittorrent;

Main(在 main 函数之前 / 作为全局变量):

const char    *Bittorrent     =   "BitTorrent protocol";

这样,您的标头会告诉每个文件有一个名为“Bittorrent”的变量,但只有您的 main.c 文件中有真正创建它的部分。

于 2013-07-11T12:19:27.817 回答
1

通过初始化变量,您可以在包含文件的每个位置定义它。假设这些模块链接在一起,您现在有多个定义,这是一个错误。

可以在标头中使用 extern 标记声明变量,然后在您的 .c 模块之一中对其进行初始化。

在您的 .h 文件中:

extern int i;

在您的 .c 文件之一中:

int i = 1;

然而,

于 2013-07-11T12:21:23.307 回答
1

另请注意,您有一个错字。

Send_fisrt_Handshake而不是Send_first_Handshake.

我可以想象你只是把它打错了你的问题。但你永远不知道;在大型代码中很难找到和修复拼写错误。:)

于 2013-07-11T13:57:36.143 回答