Быстрый (в смысле времени разработки) способ использования большого количества кода C ++ из Java - PullRequest
3 голосов
/ 08 октября 2009

Справочная информация: Мы разрабатываем приложение для физики, которое будет выполнять большой анализ данных, но наша задача - интеграция физического электронного оборудования.

В основном я хотел бы иметь возможность вызывать root (это большая библиотека анализа данных из CERN, написанная на C ++), написанная на C ++ из Java. По сути, возможность использовать классы ROOT из Java (и делать это, не тратя много времени на кодирование JNI-оболочек), является для нас наглядным примером (если это будет сложно, скорее всего, мы будем использовать Qt).

Я могу подумать о следующих методах

  • JNI - как я уже сказал - мы не хотим писать обертки для каждого класса. , ,
  • JNA - JNA не обеспечивает сопоставления C ++, но только C.
  • SWIG - Я не использовал его, но слышал, что его трудно использовать.

Другие вещи, которые могут быть полезны: у нас есть доступ к корневому исходному коду, но мы не хотим его менять. Мы хотим, чтобы результаты были переносимыми. Мы хотели бы придерживаться бесплатных библиотек. И, как я уже сказал, мы сможем использовать большую часть кода ROOT с самого начала, без суеты.

Ответы [ 9 ]

6 голосов
/ 08 октября 2009

Напишите небольшое приложение на C ++, которое читает ваш ввод из stdin и записывает вывод в stdout. Затем запустите процесс из вашего Java-приложения и прочитайте вывод из stdout.

Это лучший способ сделать это без JNI (и это довольно легко сделать)

3 голосов
/ 08 октября 2009

При любом выборе вам понадобится сделать обертку. Хотя вы не хотите писать оболочки JNI для каждого класса, вы можете написать классы C ++ более высокого уровня, которые охватывают группы методов. Тогда вам нужно только написать оболочки для классов более высокого уровня (этот подход работает и для других методов, а не только для JNI).

2 голосов
/ 24 августа 2015

Я бы порекомендовал Инструмент генерации интерфейса Dropbox djinni . Они используют его в своих кроссплатформенных мобильных приложениях для генерации интерфейсов между интерфейсами Java (Android) и Objective-C (iOS) и своей моделью данных C ++.

Facebook тоже использовал его для одного из своих приложений. Так что я бы предположил, что это довольно хорошо проверено.

См. Их выступление на CppCon для обзора того, что он делает. Взаимодействие между Java и C ++ с использованием JNI кажется особенно подверженным ошибкам.

1 голос
/ 08 октября 2009

JNIEasy поддерживает отображение классов C ++ на классы Java POJO, но стоит 399 €. Поскольку вы предпочитаете бесплатные библиотеки, вы можете искать решения, использующие что-то вроде CORBA. Это единственный способ связать классы C ++ с классами Java.

РЕДАКТИРОВАТЬ: Вы рассматривали JAS3 , это библиотека Java, похожая на root?

0 голосов
/ 08 октября 2009

если будет сложно, скорее всего мы будем использовать Qt

Почему бы тебе не сосредоточиться на этом? До сих пор вы не упомянули никаких причин, по которым Java следует отдавать предпочтение.

Если большая часть - это источник ROOT и код, который его вызывает, вы, вероятно, будете намного быстрее делать все это в C ++.
Поскольку с Qt у вас все в порядке, пользовательский интерфейс не должен сильно волноваться.

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

0 голосов
/ 08 октября 2009

Как насчет написания классов / функций, которые вам нужны в C ++, компиляции и вызова exec () для них из Java?

0 голосов
/ 08 октября 2009

Каждый раз, когда вы вызываете код C или C ++ из Java через JNI или аналогичный, вы рискуете дестабилизировать платформу Java из-за проблем с управлением памятью и / или безопасностью потоков на стороне C / C ++.

Прежде чем идти по маршруту JNI и т. Д., Я думаю, вам следует рассмотреть другие альтернативы:

  • Выньте Java из уравнения и полностью внедрите его в C ++ (или C ++ / CC #, как кто-то еще предложил).
  • Создайте приложение командной строки C ++, которое выполняет задачу, которую вам необходимо выполнить с помощью собственной библиотеки, и запустите приложение, используя один из методов java.lang.Runtime.exec.
  • Создайте «серверную» оболочку в C ++ для библиотеки, которая предоставляет функции, необходимые вам в качестве настраиваемого протокола, и кодируйте сторону Java для взаимодействия с сервером, используя HTTP, необработанные сокеты, каналы или любой другой транспортный уровень, подходящий .

Все альтернативы имеют свои недостатки, но так же как и JNI / JNA и тому подобное; см. первый абзац.

РЕДАКТИРОВАТЬ: когда вы принимаете решение использовать JNI / JNA в системе, это может иметь долгосрочные последствия. Помимо проблемы со стабильностью, вы должны учитывать переносимость (будет ли собственная библиотека работать в Windows, Linux и т. Д.), Проблемы сборки (трудно собрать собственные библиотеки в Ant и т. Д.), Проблемы с версиями платформы (будет обновление до Java 7 что-нибудь сломать?), Навыки разработчика («Джо», который сделал интеграцию JNI, оставил - кто еще знает Java, C ++ и JNI?). Сумма этих вопросов (ИМО) более значительна, чем время, необходимое для первоначальной разработки.

0 голосов
/ 08 октября 2009

Рассмотрите возможность использования C # вместо Java. Если вы уже знакомы с Java, переключиться на C # легко, и он намного лучше поддерживает для вызова нативного кода.

0 голосов
/ 08 октября 2009

Просто мысль, но можете ли вы использовать Python, поскольку Root уже поддерживает его? Вы вполне можете стать достаточно опытным за то время, которое потребуется для переноса кода на Java.

...