Boost.Extension - simple inheritance sample - why we see no animals on linux?

前端 未结 2 1402
情歌与酒
情歌与酒 2020-12-21 13:04

So I try to port some Boost.Extension samples for linux.

The sample is described here. Here is my code port (classes with animals, animal prototype, main app, gener

相关标签:
2条回答
  • 2020-12-21 13:38

    I debugged things on linux, good news:

    You are running into bullet no. 3 from Jeremy Pack's post:

    RTTI does not always function as expected across DLL boundaries. Check out the type_info classes to see how I deal with that.

    I have a tiny workaround patch (below) to boost/extension/impl/typeinfo.hpp (but you need to talk to the maintainer of Boost Extension, really). What this does is not rely on builtin comparison for RTTI typeinfo's.

    Looking at typeinfo.hpp, it seems that Windows never actually uses the typeinfo comparison, so I decided to test with the 'strcmp' fallback method, and voila:

    $ 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
    

    In particular, I can show that the type lookup from convertible_ fails at type_map.hpp, line 68;

    • When this conversion is called from the extension dll itself, the conversion happily finds the match using RTTI.
    • However, when the 'same' .get() is done from the test application (across DLL boundaries, i.e.) the RTTI is different and no such match is found, and line 74/75 are hit:

    .

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

    Patch

    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) {
    
    0 讨论(0)
  • 2020-12-21 13:55

    GCC on Linux by default has stricter linker optimization settings that MSVC on Windows. This leads to some factory patterns where classes register themselves as available appearing broken, simply because the linker optimizes away the classes. I didn't look at your code - but from the description it could be the problem.

    A related question, with an answer on how to avoid the unreferenced classes being dropped: How to force gcc to link unreferenced, static C++ objects from a library

    0 讨论(0)
提交回复
热议问题