提问人:A.D 提问时间:3/6/2021 最后编辑:kkm -still wary of SE promisesA.D 更新时间:3/7/2021 访问量:1644
Boost - 链接期间的多个定义
Boost - Multiple definitions during linking
问:
我有这两个类(我们称它们为 和 ),它们都包括 boost/archive 和 boost/serialization 文件。这些包含在我的 hpp 文件中(带有标头保护)中,用于两个类中的每一个。类(以及代码库的其他部分)包括类,因此重复完全相同的包含。A
B
A
B
据我了解,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_
A
B
为什么会发生这种情况(以及我该如何解决)?为什么升压接头防护不阻止这第二个包含?这是否与代码本身无关,而是一个构建问题?
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>
答:
1赞
sehe
3/7/2021
#1
事实上,一旦您将头文件包含在多个翻译单元(想想 .cpp 文件)中,放入头文件就会导致定义的符号成倍增加。BOOST_CLASS_EXPORT
在没有您的代码的情况下,我在这个网站上有很多完整的示例。我会搜索“user:85371 boost_class_export_key”:
- 尝试使用 boost::serialization 通过 boos::asio 套接字发送派生类
- 序列化多晶接口
- BOOST_CLASS_EXPORT_* 宏不像 register_type() 那样工作
- 提升序列化,按基类型加载存档类会给出错误的数据
- Boost 序列化 - 导出多个 CPP 文件
- 为什么 boost::serialize 不起作用,尽管一切看起来都是正确的?(“未注册类别”)
他们中的大多数都有在线多文件现场演示,并包含在答案文本中。
评论
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
我记得我有过同样的灯泡时刻。干杯!
评论
_BOOST_INCLUDES_
grep
BOOST_CLASS_EXPORT
A