Boost.Extension – 简单的inheritance样例 – 为什么我们在linux上看不到动物?

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

样本在这里描述。 这里是我的代码端口( 类与动物 , 动物原型 , 主要应用程序 ,一般所有端口的想法在这里描述 ,和一些当前的Linux进展在这里(一些样品真的按需要工作!) )。 当我在linux下编译这个样本时,它会find动物的库,但输出:

Animals not found! 

只有if(factories.empty())才会发生这种情况。

我尝试将扩展示例移植到跨平台的基础上 – 所以我在Windows下尝试了相同的代码 – 像魅力一样工作! find所有的动物和产出:

 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构build这个东西:

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

更新2:

Windows和Linux的项目文件现在在svn,所以你可以用premake创build一个项目的创build – 只有Boost,我们的svn和reflection头只有lib。

Solutions Collecting From Web of "Boost.Extension – 简单的inheritance样例 – 为什么我们在linux上看不到动物?"

我在Linux上调试了一些好消息:

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

RTTI并不总是如预期的那样在DLL边界上起作用。 看看type_info类来看看我如何处理。

我有一个小的解决方法补丁(下面)来boost/extension/impl/typeinfo.hpp (但你需要和Boost Extension的维护者交谈)。 这样做不是依赖于RTTI typeinfo的内置比较。

看看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) { 

Linux上的GCC默认情况下在Windows上有MSVC的更严格的链接器优化设置。 这导致了一些工厂模式,在这种工厂模式中,类注册自己是可用的,只是因为链接器优化了类。 我没有看你的代码 – 但从描述可能是这个问题。

一个相关的问题,回答如何避免未被引用的类被丢弃: 如何强制gcc链接库中未引用的静态C ++对象