Использование libstdc ++ скомпилированных библиотек с помощью clang ++ -stdlib = libc ++

Я работаю на C ++ под Mac OS X (10.8.2), и недавно я придумал использование возможностей C ++ 11, которые доступны через компилятор clang ++ с помощью libc ++ stdlib. Тем не менее, мне также нужно использовать некоторую библиотеку устаревших, скомпилированную и связанную с libstdc ++ (исходящую от MacPorts).

При этом у меня возникли ошибки связывания, поскольку заголовки устаревших библиотек, использующие, например, std::string , должны быть разрешены против std::__1::basic_string (т. std::__1::basic_string Реализация std::string libc ++) вместо реализации std::basic_string .

Есть ли способ смешать две библиотеки в разработке (например, используя некоторые флаги препроцессоров?)

То, что вы видите, это использование встроенных пространств имен для достижения управления версиями ABI.

Что это значит:

std::string libstdc ++ std::string это другая структура данных, чем std::string libc ++ std::string . Первый – эталонный подсчитанный дизайн, а второй – нет. Хотя они совместимы с API, они не совместимы с ABI. Это означает, что если вы std::string с libstdc ++, а затем передаете ее другому коду, связанному с libc ++, код получения будет считать, что у него есть std::string libc ++ std::string . Т.е. приемник не будет иметь понятия, что он должен увеличивать или уменьшать количество ссылок.

Без встроенных пространств имен результатом будет ошибка времени выполнения. Лучшее, на что можно надеяться, это крушение. При встроенных пространствах имен эта ошибка времени выполнения преобразуется в ошибку времени связи.

Вам программист libstdc ++ std::string и std::string libc ++ std::string выглядят одинаково. Но для компоновщика они выглядят как совершенно разные типы (ключ – пространство имен std::__1 ). И взгляд компоновщика верен. Они совершенно разные.

Так что да, вы можете манипулировать некоторыми препроцессорными флагами, чтобы связать вещи. Но тогда у вас будет чертовски время отладки результирующих ошибок времени выполнения.

Единственный способ сделать то, что вы хотите, – сделать интерфейсы между этими dylib, не включать std:: types, такие как string . Например, вы можете передать массивы char . Вы даже можете перенести владение памятью из libstdc ++ – связанного кода на libc ++ – связанный код и наоборот (они оба перейдут в один и тот же пул malloc).

Давайте будем гением компьютера.