Кажется, что большинство документации или вспомогательных библиотек, связанных с JNI (Java Native Interface), связаны с вызовом собственного кода с Java. Это, по-видимому, основное его использование, даже если оно способно больше.
Я хочу в основном работать в обратном направлении: изменить существующую (довольно большую) переносимую С++-программу, добавив к ней некоторые библиотеки Java. Например, я хочу, чтобы он вызывал базы данных через JDBC или системы очереди сообщений через JMS или отправлял электронные письма или вызывал мои собственные классы Java и т.д. Но с необработанным JNI это довольно неприятно и подвержено ошибкам.
Поэтому я бы идеально хотел написать С++-код, который может вызывать классы Java так же легко, как С++/CLI может вызывать классы CLR. Что-то вроде:
using namespace java::util::regex; // namespaces mapped
Pattern p = Pattern.compile("[,\\s]+");
array<java::lang::String> result =
p.split("one,two, three four , five");
for (int i=0; i < result.length(); i++)
std::cout << result[i] << std::endl;
Таким образом, мне бы не пришлось вручную выполнять работу по получению идентификатора метода путем передачи имени и странных строк подписи, и будет защищен от ошибок программирования, вызванных непроверенными API-интерфейсами для вызова методов. На самом деле это будет похоже на эквивалентную Java.
NB. Я ЕСМЬ ЕЩЕ РАЗГОВОР О ИСПОЛЬЗОВАНИИ JNI! В качестве базовой технологии она идеально подходит для моих нужд. Он "в процессе" и очень эффективен. Я не хочу запускать Java в отдельный процесс и делать RPC-вызовы. Сам JNI в порядке. Мне просто нужен приятный интерфейс.
Для создания эквивалентных классов С++, пространств имен, методов и т.д. должен быть создан инструмент генерации кода, чтобы точно соответствовать тому, что отображается набором классов Java, которые я указываю. Сгенерированные классы С++:
- Имейте функции-члены, которые принимают аналогично завернутые версии своих параметров, а затем делают необходимые JUDI Voodoo для выполнения вызова.
- Оберните возвращаемые значения таким же образом, чтобы я мог цеплять вызовы естественным образом.
- Поддерживать статический кеш для каждого класса идентификаторов методов, чтобы каждый раз просматривать их.
- Будьте полностью потокобезопасными, портативными, с открытым исходным кодом.
- Автоматически проверять исключения после каждого вызова метода и вызывать исключение std С++.
- Также работайте, когда я пишу собственные методы в обычном порядке JNI, но мне нужно вызвать другой код Java.
- Массив должен работать полностью последовательно между примитивными типами и классами.
- без сомнения, нужно что-то вроде глобального обернуть ссылки, когда они должны выжить вне локальной системы отсчета - опять же, должны работать одинаково для всех ссылок массива/объекта.
Есть ли такая бесплатная, открытая исходная портативная библиотека/инструмент или мне снится?
Примечание: я нашел этот существующий вопрос, но OP в этом случае не был столь же требовательным к совершенству, как и я...
Обновление: комментарий о SWIG привел меня к этому предыдущему вопросу, что, по-видимому, указывает на то, что речь идет в основном о противоположном направлении и поэтому я не буду делать то, что хочу.
ВАЖНО
- Это о возможности написания кода на С++, который управляет классами Java и объектами, а не наоборот (см. заголовок!)
- Я уже знаю, что JNI существует (см. вопрос!). Но рукописный код API JNI излишне подробен, повторяется, подвержен ошибкам, а не проверяется типом во время компиляции и т.д. Если вы хотите использовать метод кэширования Идентификаторы и объекты класса еще более подробные. Я хочу автоматически генерировать классы оболочки С++, которые заботятся обо всем этом для меня.
Обновление: Я начал работать над своим собственным решением:
https://github.com/danielearwicker/cppjvm
Если это уже существует, дайте мне знать!
NB. Если вы планируете использовать это в своем собственном проекте, не стесняйтесь, но имейте в виду, что сейчас код составляет несколько часов, и я только написал три очень неустойчивых теста.