Boost.Extension - an example of simple inheritance - why don't we see animals on linux?

So, I will try to port some Boost.Extension examples for linux .

A sample is described here . Here is my port of code ( animal classes, animal prototype , main application , the general idea of ​​the port is described here , and some current Linux progress (some samples really work as needed!) ). When I compile this sample under linux, it compiles, it finds a library with animals, but outputs:

Animals not found! 

What happens only if(factories.empty()) .

I am trying to port extension examples to a cross-platform database - so I tried the same code under the windows - it works like a charm! finds all animals and exits:

 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 

So ... Why does it behave like this on Linux with the same code? Why does it work so well under Windows?

Update:

So, how to build this material with the premiere:

  • You get svn from here (only this folder is required)
  • You will get a start for your platform or create it from the source and place it in the folder downloaded from svn
  • You must have the official Boost compiled and installed (please read the ReadMe.txt file that we provide in the directory), so you need to:
    • Boost C ++ Library (we tested with version 1.4.16)
    • Boost-Extension (we use the latest version , we added it as part of boost 'boost / extension / ** ' We had to make some chandes (actually only one) to increase the extension, so we provide it inside the Boost.Extension.Tutorial/libs/boost/extension/ folder Boost.Extension.Tutorial/libs/boost/extension/ , so when you download svn you got it, this is just the header )
    • Boost-Reflection (we use because of this tutorial , we use the latest revision , we consider it as part of boost 'boost / reflection / ** ' *, and for simplicity we recommend just placing it in Boost.Extension.Tutorial/libs/boost/reflection * )
  • Now that the official Boost is on your system, only the Boost-reflection and Boost extensions headers are in the Boost.Extension.Tutorial/libs/boost folder, the Boost.Extension.Tutorial/libs/boost executable is inside the Boost.Extension.Tutorial/ folder, which we can just call Boost.Extension.Tutorial/ premake4-build-windows.bat on Windows to get sln for Visual Studio or Boost.Extension.Tutorial/ premake-build.sh to get makefiles.
  • You can find the generated solution / make files inside the generated projects folder.
  • Good luck =)

Update 2:

Project files for Windows and Linux are now in svn , so you can get the project created with the premiere - just use Boost, our svn and reflection of the headers only lib.

+2
c ++ boost linux
Apr 29 '11 at 20:15
source share
2 answers

I debugged things on Linux, good news:

You work at bullet no. 3 from Jeremy Pak's post :

RTTI does not always work as expected across DLL boundaries. Check out the type_info classes to find out how I deal with this.

I have a tiny patch to fix (below) to boost/extension/impl/typeinfo.hpp (but you need to talk to the Boost Extension developer, really). This is independent of the built-in comparison for the RTTI type.

Looking at typeinfo.hpp, it seems that Windows never uses type comparison info, so I decided to test using the backup method 'strcmp' 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 search from convertible_ not performed on the type_map.hpp line, line 68;

  • When this conversion is called from the innermost dll library, the conversion happily finds a match using RTTI.
  • However, when the "same" .get () is executed from the test application (across the boundaries of the DLL, i.e.) the RTTI is different and such a match is not found, and line 74/75 is 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) { 
+7
Apr 30 2018-11-11T00:
source share

GCC on Linux by default has stricter linker optimization options that are MSVC on Windows. This leads to some factory patterns where classes are registered as available, seemingly broken, simply because the linker optimizes the classes. I did not look at your code, but from the description this may be a problem.

A related question with the answer to the question of how to avoid dropped classes without a link: How to get gcc to bind unpublished C ++ static objects from the library

+3
Apr 29 '11 at 20:41
source share



All Articles