Кажется, что большинство документации или вспомогательных библиотек, связанных с JNI (Java Native Interface), касаются вызова нативного кода из Java. Это, кажется, главное использование этого, хотя оно способно на большее.
Я хочу в основном работать в противоположном направлении: изменить существующую (довольно большую) переносимую программу на C ++, добавив в нее несколько библиотек Java. Например, я хочу, чтобы он вызывал базы данных через JDBC, или системы очереди сообщений через JMS, или отправлял электронные письма, или вызывал мои собственные классы Java и т. Д. Но с необработанным JNI это довольно неприятно и подвержено ошибкам.
Так что в идеале я хотел бы написать код C ++, который может вызывать классы Java так же легко, как C ++ / 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 все в порядке. Я просто хочу приятного интерфейса к нему.
Чтобы создать эквивалентные классы C ++, пространства имен, методы и т. Д., Должен был бы быть инструмент генерации кода, который бы точно соответствовал тому, что предоставляется набором классов Java, которые я определяю. Сгенерированные классы C ++ будут:
- Имеют функции-члены, которые принимают аналогичные версии своих параметров, а затем выполняют необходимое колдовство JNI для совершения вызова.
- Оберните возвращаемые значения таким же образом, чтобы я мог связывать вызовы естественным образом.
- Поддерживать статический кэш идентификаторов методов для каждого класса, чтобы не искать их каждый раз.
- Будьте полностью поточнобезопасным, переносимым, с открытым исходным кодом.
- Автоматически проверять исключения после каждого вызова метода и создавать стандартное исключение C ++.
- Также работает, когда я пишу нативные методы обычным способом JNI, но мне нужно обращаться к другому Java-коду.
- Массив должен работать полностью согласованно между примитивными типами и классами.
- Без сомнения, понадобится что-то вроде global для переноса ссылок, когда им нужно выжить вне локальной системы отсчета - опять же, должно работать одинаково для всех ссылок на массив / объект.
Существует ли такая бесплатная переносимая библиотека / инструмент с открытым исходным кодом или я сплю?
Примечание: я нашел этот существующий вопрос , но ОП в этом случае не был настолько требователен к совершенству, как я ...
Обновление: комментарий о SWIG привел меня к к этому предыдущему вопросу , который, кажется, указывает на то, что он в основном противоположен и поэтому не будет делать то, что я хочу.
ВАЖНО
- Речь идет о способности писать код C ++, который манипулирует классами и объектами Java, а не наоборот (см. Заголовок!)
- Я уже знаю, что JNI существует (см. Вопрос!), Но рукописный код для API-интерфейсов JNI излишне многословен, повторяется, подвержен ошибкам, не проверяется во время компиляции и т. Д. Если вы хотите кэшировать метод Идентификаторы и объекты классов еще более многословны. Я хочу автоматически создавать классы-оболочки C ++, которые позаботятся обо всем этом для меня.
Обновление: Я начал работать над собственным решением:
https://github.com/danielearwicker/cppjvm
Если это уже существует, пожалуйста, дайте мне знать!
NB. Если вы планируете использовать это в своем собственном проекте, не стесняйтесь, но имейте в виду, что прямо сейчас коду уже несколько часов, и я пока написал только три очень напряженных теста.