Boost C++ 库

one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

设计原理 - Boost C++ 函数库
PrevUpHomeNext

在讨论该库时,很多人问及 ABI 稳定性以及库是否应处理它。有人认为实现 ABI 稳定性会很有用,但这会增加大量开销并降低库的易用性。对于那些不需要跨编译器 ABI 稳定性的用户来说,这种功能将是“过度杀伤”。

决定使该库更简单、更底层,以便需要它来构建 ABI 稳定插件系统的用户可以使用它,同时又不增加其他用户的开销。

有一些开源 C++ 插件系统。它们大多强制用户使用某些预定义的 API。问题在于,所有这些 API 都各不相同。

为了更易于使用,Boost.DLL 不强制规定 API。由用户自行设计合适的 API。

该库的某些方法使用了 boost::filesystem::path 或返回 std::vector<std::string>。乍一看这可能显得不理想,但有其原因。

boost::filesystem::path 允许透明地使用 Unicode 字符串与非 Unicode 字符串。使用它为库提供了更用户友好的界面,而性能开销不明显,因为 boost::filesystem::path 接受方法时发生的都是慢速文件系统操作。

std::vector<std::string> 变量由 library_info 方法返回。查询库本身就是一个缓慢的过程:它会随机读取磁盘文件的部分内容,并执行有时会根据节或导出符号数量具有线性复杂度的算法。返回 std::vector<std::string> 简化了实现,并且用户在查询后无需保留 library_info 的实例。在很少调用的方法中,不明显的性能开销似乎是合理的。

其他方法被假定为热点路径,并尽可能进行了优化。

通过 shared_library(program_location()) 进行自加载,而不是使用 shared_library::load_self() 成员方法,有一个非常充分的理由。这个理由是需要在任何地方(甚至主二进制文件)调用 shared_library(this_line_location()) 的能力。我们需要它来将插件链接到二进制文件中,并创建一个透明的引用计数机制。

我认为创建执行完全相同功能的多个接口是不合理的,因此 shared_library(program_location())shared_library(this_line_location()) 在没有 shared_library::load_self() 的情况下被使用。

名称修饰取决于源代码,例如 "boost::foo" 可能是 foo 函数或 foo 变量。根据这些知识,它必须以不同的方式进行名称修饰。如果 foo 是一个接受参数的重载函数,则会出现更多问题:"boost::foo(variant<int, short>)"。在这种情况下,必须指定参数的完整名称,它可能是 boost::variant<int, short>variant<int, short, void_, void_> ...

有一个想法是允许用户前向声明函数并从中生成修饰后的名称

namespace boost { void foo(variant<int, short>); }

std::string mangled_name = boost::dll::magic_mangle(boost::foo);

但这个想法因为链接器问题和在编译时无法可靠地从编译器内部获取修饰后的符号名称而彻底失败了。

因此,别名被认为是“两害相权取其轻”。

BOOST_DLL_ALIAS(boost::foo, foo_variant) // in plugin
"foo_variant" // in plugin importer


PrevUpHomeNext