Доброго времени суток.
Дали для пользования библиотеку, собранную старым GCC. Использовать именно эту библиотеку, а не какую другую, придется в силу ее специфики.
Разумеется в библиотеке ABI еще от 98 стандарта, т.е. мой модуль удачно слинковывается с ней, если использовать флаг компиляции -D_GLIBCXX_USE_CXX11_ABI=0
Вся проблема в том, что я использую дополнительные библиотеки (curl, libxml и т.п.), и их теперь тоже приходиться пересобирать с флагом -D_GLIBCXX_USE_CXX11_ABI=0, ну или точнее, иметь их дополнительную сборку с указанным флагом из-за одной "корявой" библиотеки.
Так вот существует ли возможность как-то выйти из этой ситуации, скрестив ужа с ежом, и использовать в одном модуле библиотеки с разным ABI?
Re: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемой библиотеки
Здравствуйте, dosik, Вы писали:
D>Доброго времени суток. D>Дали для пользования библиотеку, собранную старым GCC. Использовать именно эту библиотеку, а не какую другую, придется в силу ее специфики. D>Разумеется в библиотеке ABI еще от 98 стандарта, т.е. мой модуль удачно слинковывается с ней, если использовать флаг компиляции -D_GLIBCXX_USE_CXX11_ABI=0 D>Вся проблема в том, что я использую дополнительные библиотеки (curl, libxml и т.п.), и их теперь тоже приходиться пересобирать с флагом -D_GLIBCXX_USE_CXX11_ABI=0, ну или точнее, иметь их дополнительную сборку с указанным флагом из-за одной "корявой" библиотеки. D>Так вот существует ли возможность как-то выйти из этой ситуации, скрестив ужа с ежом, и использовать в одном модуле библиотеки с разным ABI?
ну, как вариант, написать dll-прослойку со старым аби, с которой слинковать библиотеку, а для остального кода использовать новое аби
Re[2]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемой библиотеки
Здравствуйте, wl., Вы писали:
wl.>ну, как вариант, написать dll-прослойку со старым аби, с которой слинковать библиотеку, а для остального кода использовать новое аби
Ну вот первых — Linux, так что so. А во вторых, что-то с трудом представляю как это возможно.
Re[3]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемой библиотеки
Здравствуйте, dosik, Вы писали:
D>Здравствуйте, wl., Вы писали:
wl.>>ну, как вариант, написать dll-прослойку со старым аби, с которой слинковать библиотеку, а для остального кода использовать новое аби
D>Ну вот первых — Linux, так что so. А во вторых, что-то с трудом представляю как это возможно.
не очень понял, что именно невозможно? Для динамических либ насколько я понимаю, аби не важен, там главное calling convention. для теста можно попробовать экспортировать одну функцию, чтобы проверить, будет ли такая конструкция работать в принципе
Re[4]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемо
Здравствуйте, wl., Вы писали:
wl.>не очень понял, что именно невозможно? Для динамических либ насколько я понимаю, аби не важен, там главное calling convention.
Ещё как важен. ABI должно совпадать. И всё равно какая там сборка: статическая или динамическая через so/dll.
wl.> для теста можно попробовать экспортировать одну функцию, чтобы проверить, будет ли такая конструкция работать в принципе
Если передаешь объекты С++, то значение _GLIBCXX_USE_CXX11_ABI должно совпадать с обоих сторон. Иначе гарантированно работать не будет.
Но тут можно сделать важное замечание: если объектов C++ в интерфейсе библиотеки нет, то и от флага _GLIBCXX_USE_CXX11_ABI зависимости не будет.
Поэтому повсеместно используется такой подход: сама программа или библиотека пишется на том языке на котором удобно (хоть на С++, хоть на Python, хоть на чём) с любыми опциями компилятора. Но наружу вытаскивается только интерфейс на С. Тут дело в том, что он на большинстве платформ просто стандартизирован и таким образом части программы оказываются автоматически совместимыми между собой.
И такая обёртка C ↔ C++ пишется вручную довольно просто.
Например, если раньше метод принимал на вход на чтение std::string, то можно написать прокси-функцию, которая возьмёт этот параметр, заменит его на пару параметров const char* и size_t (указатель на начало и длину), вызовет функцию из so с этими параметрами, а функция из so из этих данных снова воссоздаст std::string, но который уже будет в другом пространстве ABI, то есть теперь этот std::string можно безболезненно передавать дальше в проблемную библиотеку.
В общем ничего сложного. Хотя, конечно, довольно муторно каждый раз писать код упаковки и распаковки какого-нибудь std::unordered_set, поэтому встречаются всякие тулзы по автоматизации этих действий.
Да даже вот тут в соседнем разделе кто-то пишет генератор таких обёрток: http://rsdn.org/forum/prj/6425341
Ну а совет вынести эту библиотеку в отдельную so-шку всё же хороший. Меньше будет возможности накосячить при сборке.
То есть главное, что нужно сделать, это собрать проблемную библиотеку в so, но выставить наружу только интерфейс в стиле C.