-D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемой библиотеки
От: dosik Россия www.dosik.ru
Дата: 23.02.17 00:34
Оценка:
Доброго времени суток.
Дали для пользования библиотеку, собранную старым 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 лишь для одной подключаемой библиотеки
От: wl. Россия  
Дата: 01.03.17 09:16
Оценка:
Здравствуйте, 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 лишь для одной подключаемой библиотеки
От: dosik Россия www.dosik.ru
Дата: 01.03.17 11:02
Оценка:
Здравствуйте, wl., Вы писали:

wl.>ну, как вариант, написать dll-прослойку со старым аби, с которой слинковать библиотеку, а для остального кода использовать новое аби


Ну вот первых — Linux, так что so. А во вторых, что-то с трудом представляю как это возможно.
Re[3]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемой библиотеки
От: wl. Россия  
Дата: 01.03.17 19:53
Оценка:
Здравствуйте, dosik, Вы писали:

D>Здравствуйте, wl., Вы писали:


wl.>>ну, как вариант, написать dll-прослойку со старым аби, с которой слинковать библиотеку, а для остального кода использовать новое аби


D>Ну вот первых — Linux, так что so. А во вторых, что-то с трудом представляю как это возможно.


не очень понял, что именно невозможно? Для динамических либ насколько я понимаю, аби не важен, там главное calling convention. для теста можно попробовать экспортировать одну функцию, чтобы проверить, будет ли такая конструкция работать в принципе
Re[4]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемо
От: watchmaker  
Дата: 01.03.17 22:02
Оценка:
Здравствуйте, 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
Автор: GhostCoders
Дата: 22.04.16



Ну а совет вынести эту библиотеку в отдельную so-шку всё же хороший. Меньше будет возможности накосячить при сборке.
То есть главное, что нужно сделать, это собрать проблемную библиотеку в so, но выставить наружу только интерфейс в стиле C.
Отредактировано 01.03.2017 22:02 watchmaker . Предыдущая версия .
Re[5]: -D_GLIBCXX_USE_CXX11_ABI=0 лишь для одной подключаемо
От: wl. Россия  
Дата: 06.03.17 18:23
Оценка:
Здравствуйте, watchmaker, Вы писали:

хм... Спасибо за разъяснение, теперь понятно, зачем Нинтендо делает так:

extern "C" bool nnosThreadIsAlive(nnosThread* p)
{
    nn::os::Thread* pThread = reinterpret_cast<nn::os::Thread*>(p);
    return pThread->IsAlive();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.