链接静态和动态库时违反ODR [英] ODR violation when linking static and dynamic library

查看:81
本文介绍了链接静态和动态库时违反ODR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

链接包含不同版本的boost的静态cpp库和动态cpp库会违反ODR吗?

Will linking a static cpp lib and a dynamic cpp lib, both containing different versions of boost, violate ODR?

我正在开发iPhone应用程序.对于最终的可执行文件,我需要链接一个静态库libstatic1.a和一个动态框架libdyanamic1.

I am working on an iphone application. For final executable, I need to link a static library say libstatic1.a and a dynamic framwork say libdyanamic1.

libstatic1.a包含boost的某些版本,例如boost 1.x,而libdynamic1包含boost的另一个版本,例如boost1.y.现在将链接这两者的最终可执行文件违反ODR规则吗?

libstatic1.a contains some version of boost, say boost 1.x and libdynamic1 contains another version of boost say boost 1.y. Now will final executable which links both of these, violate ODR rule?

libdynamic1中的符号可见性:我使用 nm -g -C libdynamic1 检查了libdynamic1中存在的符号,并观察到列表中存在boost线程池和boost文件系统的符号.

Symbol visibility in libdynamic1: I inspected symbols present in libdynamic1 using nm -g -C libdynamic1 and observed that symbols of boost threadpool and boost filesystem are present in the list.

如果我违反ODR,该如何处理情况?(到目前为止,我已经在多个设备上测试了可执行文件,但没有遇到任何问题.)

If I am violating ODR, what are my options to handle the situation? (So far I have tested the executable on multiple devices and have not experienced any issue.)

推荐答案

该标准仅涉及程序",其中程序"是一组链接在一起"的翻译单元,每个翻译单元由一系列声明 [basic.link] .对于涉及动态库的问题,ODR也只与程序"有关,这并不是一件容易的事.由于程序"必须包含 main 函数

The standard only talks about "programs" where a "program" is a set of translation units "linked together", each consisting of a sequence of declarations [basic.link]. Arguing the ODR, which also concerns itself only with "programs", when it comes to questions involving dynamic libraries is not that straight forward. Since a "program" is required to contain a main function [basic.start.main]/1, a dynamic link library will generally not qualify as a "program" on its own.

严格来说,我认为动态库只应被视为另一套翻译单元,它们与其余部分链接"在一起形成最终程序.因此,该程序实际上只有在所有图像都已加载到内存中并且动态链接完成后才真正完成(运行时动态链接似乎会使问题进一步复杂化,但是我猜这里可以忽略).从这个意义上讲,您所描述的程序(将静态库和动态库链接在一起,每个库都使用不同版本的boost)几乎肯定会违反ODR,因为您将拥有多个翻译单元,例如,使用相同实体的不同定义

Strictly speaking, I think a dynamic library would have to be viewed as just another set of translation units that are "linked" with the rest to form the final program. Thus, the program would really only be complete once all images have been loaded into memory and dynamic linking is finished (run-time dynamic linking would seem to further complicate the matter, but can be ignored here I guess). In this sense, the program described in your question (linking both the static and the dynamic library where each is using a different version of boost) will almost certainly be violating the ODR since you are going to have multiple translation units which are, e.g., using different definitions of the same entities [basic.def.odr]/12.

但是,实际上,此问题高度依赖于平台和工具链.在ABI级别上,通常可以发现符号可以具有的链接类型比在C ++中的语言级别上可以找到的链接类型更多.例如,在Windows上,构建动态库时通常必须明确指定应导出哪些符号,默认情况下,所有名称都在库内部.另一方面,在基于ELF的Linux上,情况并非如此.但是,您似乎可以使用 -fvisibility = hidden 选项,将GCC切换为更类似于Windows的默认设置,其中您的库只会导出您明确告知的内容.请注意,您一定与库导出接口中的boost没有任何关系,因为这显然会导致case/hellip;

In practice, however, this issue is highly platform- and toolchain-dependent. At the ABI level, you typically find that the types of linkage a symbol can have are more differentiated than what you find at the language level within C++. On Windows, for example, you typically have to explicitly specify which symbols should be exported when building a dynamic library, all names are internal to the library by default. On ELF-based Linux, on the other hand, that is famously not the case. It would seem, however, that you can use the -fvisibility=hidden option to switch GCC to a more Windows-like default where your library will only export what you explicitly tell it to. Note that you must not have anything to do with boost in the interface your library exports as that will obviously lead to undefined behavior in your case…

这篇关于链接静态和动态库时违反ODR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆