Boost - 链接期间的多个定义

Boost - Multiple definitions during linking

提问人:A.D 提问时间:3/6/2021 最后编辑:kkm -still wary of SE promisesA.D 更新时间:3/7/2021 访问量:1644

问:

我有这两个类(我们称它们为 和 ),它们都包括 boost/archive 和 boost/serialization 文件。这些包含在我的 hpp 文件中(带有标头保护)中,用于两个类中的每一个。类(以及代码库的其他部分)包括类,因此重复完全相同的包含。ABAB

据我了解,boost 库中的标头保护应该可以防止库文件在此处第二次包含;但事实似乎并非如此。 我甚至在包含组周围放置了另一个标头保护,以确保它不会被多次包含;然而,在链接时,我得到了一个多重定义的错误。

包括在课堂上 :A

#ifndef _A_H
#define _A_H


// Other none boost includes for class A
#ifndef _BOOST_INCLUDES_
#define _BOOST_INCLUDES_
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#endif

class A{/*...*/};

类在其头文件中具有相同的 include 块(和 guard)。代码的其他部分在某些时候也包含类或类,但问题源于此处的 include 中的某些内容。B_BOOST_INCLUDES_AB

为什么会发生这种情况(以及我该如何解决)?为什么升压接头防护不阻止这第二个包含?这是否与代码本身无关,而是一个构建问题?

Makefile 提取:

BOOST_ROOT  := myPathToBoost/boost_1_75_0/
BOOST_LIBS  := -L$(BOOST_ROOT)stage/lib/ -lboost_serialization
BOOST       := -I $(BOOST_ROOT) $(BOOST_LIBS)

$(CM_OBJS): $(CM_SOURCES)
    $(CC) $(FLAGS) -MMD $(BOOST) -c $(INCLUDES) -o $@ $< $(LIBS)

链接器错误为:

/usr/bin/ld: /projectPath/build/clientMain.o:(.bss+0x0): multiple definition of `boost::archive::detail::extra_detail::init_guid<EndGame>::g'; /projectPath/build/Register.o:(.bss+0x0): first defined here

并且此消息对每个包含重复;文件名各不相同,内容也各不相同。::init_guid<X>

C++ 提升 链接器错误 多定义错误

评论

0赞 Ted Lyngmo 3/6/2021
请在问题中包含确切的错误消息。另外,什么是?我以前从未见过。_BOOST_INCLUDES_
0赞 A.D 3/6/2021
@TedLyngmo BOOST_INCLUDES 只是我制作的标头保护,以试图防止预处理器多次放置包含
1赞 rustyx 3/6/2021
看起来您的项目中有多个BOOST_CLASS_EXPORT(EndGame)
0赞 A.D 3/6/2021
@rustyx我刚刚做了一个 on,我发现它只出现了 1 次,而且它恰好在类的头文件中。' ./projectPath/A.hpp:BOOST_CLASS_EXPORT_GUID(EndGame, “EndGame”)'grepBOOST_CLASS_EXPORTA
1赞 rustyx 3/6/2021
不要在我的办公桌自动取款机上,试着在谷歌上搜索“放BOOST_CLASS_EXPORT”。

答:

1赞 sehe 3/7/2021 #1

事实上,一旦您将头文件包含在多个翻译单元(想想 .cpp 文件)中,放入头文件就会导致定义的符号成倍增加。BOOST_CLASS_EXPORT

在没有您的代码的情况下,我在这个网站上有很多完整的示例。我会搜索“user:85371 boost_class_export_key”:

他们中的大多数都有在线多文件现场演示,并包含在答案文本中。

评论

0赞 A.D 3/8/2021
我可能误解了这一点,但我的标题保护对此没有帮助:“一旦您将头文件包含在多个翻译单元中”?并防止第二次包含?
3赞 sehe 3/8/2021
@A.D 是的,你误会了。标头防护装置可防止在同一翻译单元中多次包含标头。顾名思义:TU 是翻译的_unit,因此一个单位对另一个单位一无所知,而头卫不可能在那里工作。在编译器转换阶段之后,链接器仍将看到所有包含重复定义的对象。
1赞 A.D 3/8/2021
啊!翻译单元的标题防护装置!现在你说出来很明显了;但这是我第一次看到有人说得这么清楚+1
1赞 sehe 3/8/2021
我记得我有过同样的灯泡时刻。干杯!