2

所以我尝试为 linux 移植一些 Boost.Extension 示例

该示例在此处进行了描述。这是我的代码移植(带有动物的类动物原型主应用程序、一般所有移植的想法都在这里描述,以及一些当前的 linux 进展在这里(一些示例确实可以根据需要工作!))。当我在它编译的 linux 下编译这个示例时,它会找到带有动物的库,但输出:

Animals not found!

这只会发生if(factories.empty())

我尝试将扩展示例移植到跨平台基础上 - 所以我在 Windows 下尝试了相同的代码 - 就像一个魅力!查找所有动物和输出:

Creating an animal using factory:
Cougar factory Created an animal:
cougar Age: 2 Creating an animal using
factory: Leopard factory Created an
animal: leopard Age: 3 Creating an
animal using factory: Puma factory
Created an animal: puma Age: 4
Creating an animal using factory:
Wildcat factory Created an animal:
wildcat Age: 5

那么......为什么它在具有相同代码的linux上表现如此?为什么它在 Windows 下运行得这么好?

更新:

那么如何使用 premake 构建这些东西:

  1. 你从这里得到svn(只需要这个文件夹)
  2. 可以为您的平台获取 premake 或从源代码构建它并将其放入您从 svn 下载的文件夹中
  3. 您应该已经编译并安装了官方的 Boost(请阅读我们在目录中提供的 ReadMe.txt 文件),所以需要什么:
    • Boost C++ 库 (我们测试了 1.4.16 版)
    • Boost-Extension(我们使用最新版本,我们将其作为 boost 'boost/extension/ **' 的一部分进行处理,我们必须制作一些 chandes(实际上只有一个)来提升扩展,所以我们在Boost.Extension.Tutorial/libs/boost/extension/文件夹中提供它,所以当你下载 svn 时你得到了它,它只是标题
    • Boost-Reflection(我们使用它是因为本教程,我们使用最新版本,我们将它作为 boost 'boost/reflection/ **' 的一部分来处理 *为了简单起见,我们建议将其放入Boost.Extension.Tutorial/libs/boost/reflection*
  4. 现在,当官方 Boost 在您的系统中时,文件夹中只有头文件 Boost-reflection 和 Boost-extension Boost.Extension.Tutorial/libs/boost,premake4 可执行文件在Boost.Extension.Tutorial/文件夹中,我们可以简单地调用Boost.Extension.Tutorial/ premake4-build-windows.batwindows 来获取 Visual Studio 的 sln 或 Boost.Extension.Tutorial/ premake-build.sh获取 makefile。
  5. 您可以在生成的项目文件夹中找到生成的解决方案/makefile。
  6. 祝你好运!=)

更新 2:

Windows 和 Linux 的项目文件现在在 svn 中,因此您可以使用 premake 进行项目创建 - 只有 Boost、我们的 svn 和反射头文件 lib。

4

2 回答 2

7

我在linux上调试了东西,好消息:

你遇到了子弹号。3 来自 Jeremy Pack 的帖子

RTTI 并不总是按预期跨 DLL 边界运行。查看 type_info 类,看看我是如何处理的。

我有一个很小的解决方法补丁(如下)boost/extension/impl/typeinfo.hpp(但你需要与 Boost Extension 的维护者交谈,真的)。这并不依赖于 RTTI 类型信息的内置比较。

查看 typeinfo.hpp,似乎 Windows 从未真正使用过 typeinfo 比较,所以我决定使用“strcmp”回退方法进行测试,瞧:

$ LD_LIBRARY_PATH=. ./Simple-Inheritance 
Creating an animal using factory: Cougar factory
Created an animal: cougar Age: 2
Creating an animal using factory: Leopard factory
Created an animal: leopard Age: 3
Creating an animal using factory: Puma factory
Created an animal: puma Age: 4
Creating an animal using factory: Wildcat factory
Created an animal: wildcat Age: 5

特别是,我可以convertible_在 type_map.hpp 第 68 行显示类型查找失败;

  • 当从扩展 dll 本身调用此转换时,转换很高兴使用 RTTI 找到匹配项。
  • 但是,当从测试应用程序(跨 DLL 边界,即)完成“相同”的 .get() 时,RTTI 是不同的并且没有找到这样的匹配,并且第 74/75 行被命中:

.

73        if (it == instances_.end()) {
74          holder = new type_holder<StoredType>;
75          it = instances_.insert(std::make_pair(t, holder)).first;
76        }

修补

diff --git a/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp b/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
index 843fed2..09fc353 100644
--- a/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
+++ b/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
@@ -50,7 +50,7 @@ struct type_info_handler<default_type_info, ClassType>

 // This list should be expanded to all platforms that successfully
 // compare type_info across shared library boundaries.
-#if defined(__APPLE__) || defined(__GNUC__) || \
+#if defined(__APPLE__) || \
     defined(BOOST_EXTENSION_FORCE_FAST_TYPEINFO)
 namespace boost {
 namespace extensions {
@@ -90,7 +90,7 @@ inline bool operator>(const default_type_info& first,
 }  // namespace extensions
 }  // namespace boost
 #else  // OTHER OS
-#include <string>
+#include <cstring>
 namespace boost { namespace extensions {
 inline bool operator<(const default_type_info& first,
                const default_type_info& second) {
于 2011-04-30T00:05:38.130 回答
3

默认情况下,Linux 上的 GCC 具有比 Windows 上的 MSVC 更严格的链接器优化设置。这导致了一些工厂模式,其中类将自己注册为可用出现损坏,仅仅是因为链接器优化了类。我没有查看您的代码 - 但从描述来看,这可能是问题所在。

一个相关的问题,回答了如何避免删除未引用的类:How to force gcc to link unreferenced, static C++ objects from a library

于 2011-04-29T20:41:20.363 回答