Boost.Extension - простой пример наследования - почему мы не видим животных в Linux? - PullRequest
2 голосов
/ 30 апреля 2011

Так что я пытаюсь портировать некоторые образцы Boost.Extension для Linux .

Образец описан здесь . Вот мой кодовый порт ( классы с животными , прототип животного , основное приложение , общий вся идея порта описана здесь , и некоторый текущий прогресс в Linux (некоторые примеры действительно работают по мере необходимости!) ). Когда я компилирую этот пример под Linux, он компилируется, он находит библиотеку с животными, но выводит:

Animals not found!

Что должно случиться только if(factories.empty()).

Я пытаюсь портировать образцы Extension на кроссплатформенную базу - поэтому я пробовал один и тот же код под 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. Вы получаете предварительную версию для своей платформы или собираете ее из источника и помещаете ее в папку, которую вы скачали с svn
  3. Вы должны иметь официальный Boost, скомпилированный и установленный (пожалуйста, прочитайте файл ReadMe.txt, который мы предоставляем в каталоге), так что нужно:
    • Boost C ++ библиотеки (мы тестировали с версией 1.4.16)
    • Boost-Extension (мы используем последняя ревизия , мы называем его частью буста 'boost / extension / **' Мы должны были сделать некоторые изменения ( на самом деле только один) для расширения расширения, поэтому мы предоставляем его в папке Boost.Extension.Tutorial/libs/boost/extension/, поэтому, когда вы загрузили svn, вы получили его, это только заголовок )
    • Boost-Reflection (мы используем его из-за этого урока , мы используем последняя ревизия , мы рассматриваем его как часть Boost / Reflection / ** '* и для простоты мы рекомендуем просто поместить его в Boost.Extension.Tutorial/libs/boost/reflection *)
  4. Теперь, когда в вашей системе установлен официальный Boost, в папке Boost.Extension.Tutorial/libs/boost находятся только заголовок Boost-отражение и Boost-расширение, исполняемый файл premake4 находится внутри папки Boost.Extension.Tutorial/, мы можем просто вызвать Boost.Extension.Tutorial/ premake4-build-windows.bat в Windows, чтобы получить sln для Visual Студия или Boost.Extension.Tutorial/ premake-build.sh, чтобы получить make-файлы.
  5. Вы можете найти сгенерированные файлы решений / make-файлов в папке сгенерированных проектов.
  6. Удачи! =)

Обновление 2:

Файлы проекта для Windows и Linux теперь находятся в svn , так что вы можете создавать проекты с помощью premake - просто используйте Boost, наш svn и отражающий заголовок только lib.

Ответы [ 2 ]

7 голосов
/ 30 апреля 2011

Я отлаживал вещи в Linux, хорошие новости:

Вы столкнулись с bullet no. 3 из поста Джереми Пак :

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.
  • Однако, когда ' same ' .get () выполняется из тестового приложения (через границы DLL, то есть), 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        }

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) {
3 голосов
/ 30 апреля 2011

GCC в Linux по умолчанию имеет более строгие настройки оптимизации компоновщика, чем MSVC в Windows.Это приводит к тому, что некоторые фабричные шаблоны, в которых классы регистрируются как доступные, выглядят неработающими просто потому, что компоновщик оптимизирует классы.Я не смотрел на ваш код - но из описания это может быть проблемой.

Смежный вопрос с ответом о том, как избежать исключения классов без ссылок: Как заставить gcc сделатьсвязывать статические объекты C ++ без ссылок из библиотеки

...