Обертывание библиотеки Java с C++ (JNI)

У меня есть большая программа, написанная на C++, которая должна использовать определенную библиотеку Java. В идеале я хотел бы создать эквивалентную библиотеку C++, которая обернет этот существующий код Java. Поэтому я изучал API вызова JNI.

Поскольку я не очень опытный программист, и у меня также нет опыта работы с JNI и многоязычным программированием, я был бы очень признателен за некоторые общие советы / подсказки / советы относительно того, как решать эту проблему.

Вещи, которые мне было бы особенно интересно узнать:

  1. Должен ли каждый класс Java в библиотеке Java отображаться на связанный класс C++? Т.е. в моей библиотеке C++ будет ли класс, каждый из которых вызывает JVM для определенного класса Java? Или у меня будет единственная JVM, через которую все получают доступ? Каков наилучший способ сделать это и почему?
  2. Каков будет основной процесс и архитектура для этого?
  3. Существуют ли какие-либо конкретные ресурсы для создания библиотеки C++ из библиотеки Java с использованием API вызова?

Большое спасибо!

1 ответ

Я делал это раньше, но это не для слабонервных, особенно если ваш интерфейс между двумя языками сложен. Отладка также может быть болью в этой ситуации.

Чтобы ответить на ваши вопросы:

  1. Вы должны начать с определения того, какие функции из библиотеки Java вам нужны для доступа в вашей программе на C++. Это всего лишь несколько задач? Попробуйте сделать очень простой интерфейс от C++ до Java в этом случае. Это сложно? Затем вам нужно начать отображать Java-классы на C++, и чем больше вам нужно, тем больше будет работы.

  2. Конец q1 - это действительно Сорта q2. Ваша программа на C++ запустит одну JVM, которая будет работать как часть вашей программы. Когда вы выполняете вызовы через C++, данные будут переданы в JVM, затем будет выполнен код Java, а затем возвращенные значения переданы обратно. Это влечет за собой затраты производительности, поэтому вызов небольших функций, таких как add(int,int) через JNI было бы дороже, чем просто делать это в C++.

  3. Есть много основных руководств, которые вы можете использовать в Google, чтобы начать. Простое управление запуском базовой JVM из C++ и выполнение вызова на самом деле немного трудоемкие, поскольку вам нужно правильно определить пути к библиотекам JVM, или это не работает (если они не улучшили это, прошло много лет с тех пор, как я пытался). Поэтому вы можете сначала проверить это, прежде чем задавать более конкретные вопросы о JNI и функциях отображения.

Альтернативный вариант (который может или не может быть невозможным в зависимости от вашей библиотеки и варианта использования) - просто написать какой-нибудь сервис-оболочку вокруг вашей библиотеки, фактически на Java. А затем отправляйте запросы к нему через JSON-HTTP или какую-либо систему обмена сообщениями.

Еще более альтернативный вариант, переписать все, что библиотека делает в C++.

Вы можете использовать библиотеку scapix:: link:: java C++ JNI для генерации заголовков C++ для любого кода Java, а затем легко получить доступ к этому коду Java из C++. Вот пример:

#include <scapix/java_api/java/lang/System.h>
#include <scapix/java_api/java/util/Locale.h>
#include <scapix/java_api/java/text/DateFormatSymbols.h>

using namespace scapix::link::java;
using namespace scapix::java_api;

void test1()
{
    // C++ objects are automatically converted to and from corresponding Java types.
    // This works for any type supported by scapix::link::java::convert() interface,
    // which supports many STL types and can be extended for your own types.

    std::string version = java::lang::System::getProperty("java.version");
    std::vector<std::string> languages = java::util::Locale::getISOLanguages();
    std::vector<std::vector<std::string>> zone_strings = java::text::DateFormatSymbols::getInstance()->getZoneStrings();
    std::map<std::string, std::string> properties = java::lang::System::getProperties();
}
Другие вопросы по тегам