Подвержен ли Java Native Interface (JNI) проблемам совместимости C ++ ABI?
Я разрабатываю приложение на Java. Я хотел бы использовать собственный интерфейс Java (JNI) для вызова функций в библиотеке C ++. У меня есть доступ к коду библиотеки C ++, и я могу перестроить его, как бы мне ни потребовалось. (Например, я могу статически связать среду выполнения C ++.)
Я могу потребовать, чтобы у моих пользователей была JRE 6 или выше, но я не могу требовать от них наличия какой-либо конкретной среды выполнения C ++.
Сотрудник указал мне на эту статью в блоге: http://www.trilithium.com/johan/2005/06/static-libstdc/, который не рекомендует использовать динамически загружаемый код C ++.
Другой коллега указал мне на этот отчет об ошибке: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4694590, в котором подробно описано, как эти проблемы были решены в Java 1.4.2.
Суть проблемы, насколько я понимаю, в том, что бинарный интерфейс libstdc ++ часто меняется. Если приложение C ++ загружает общую библиотеку C ++, созданную с помощью другого компилятора, две несовместимые библиотеки libstdc ++ будут загружены в память одновременно.
В отчете об ошибке объясняется решение для Java 1.4.2: «Мы статически связываем среду выполнения C ++ в JDK и включили сценарий компоновщика, чтобы скрыть символы из libstdc ++ и других внутренних символов. В результате эти символы становятся невидимыми для кода JNI, а когда некоторые собственный код должен вызывать среду выполнения C ++, вызов будет разрешен с помощью соответствующей библиотеки libstdc ++. итак. Есть еще две библиотеки libstdc ++. поэтому загружаются одновременно, но это должно быть безопасным. "
У меня есть несколько вопросов по этому поводу.
Во-первых, продолжает ли OpenJDK придерживаться этого подхода?
[РЕДАКТИРОВАТЬ: Я задал этот вопрос в списке рассылки OpenJDK build-dev. Ответ - да, HotSpot по-прежнему статически связывает libstdc ++, но, очевидно, «большинство дистрибутивов Linux исправляют это». Другой разработчик отмечает, что для этого даже не требуется патч: «Установка STATIC_CXX = false должна быть достаточной (по умолчанию true).»]
Во-вторых, даже в этом случае, действительно ли полезно иметь две несовместимые библиотеки libstdc ++, загруженные одновременно?
В-третьих, решает ли этот подход (чтобы скрыть символы в JDK) все проблемы совместимости?
В упомянутой выше статье блога говорится, что «код, скомпилированный для разных ABI, просто несовместим с двоичными кодами». И позже, «поддержка языковой среды выполнения обычно полагается на некоторые совместно используемые данные, например, для доступа к какой-то блокировке или глобальной структуре данных (аналогично тому, как программам на C требуется общая ошибка)».
Это звучит так, будто проблема не может быть решена.
Опять же, может быть, несовместимость ABI больше не проблема. Этой статье в блоге больше шести лет. Один ответ на другой вопрос о stackoverflow (совместимость с GCC ABI) утверждает, что «Начиная с gcc-3.4.0, ABI поддерживает прямую совместимость ". Это было успешно?
Буду признателен за любые рекомендации по этим вопросам. (И привет, спасибо, что прочитали все это!)
РЕДАКТИРОВАТЬ
Мой вопрос становился довольно длинным, поэтому я не стал вдаваться в подробности. Чтобы ответить на комментарии Уилла:
- Мне нужно только вызвать внешние "C" функции. (Например, я использую javah для создания файла заголовка C.)
- Мне не нужно взаимодействовать со средой выполнения C ++ в JVM. (Мне просто нужно отправить строки в библиотеку C ++.)