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

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

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

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

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

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


person jb.    schedule 07.10.2009    source источник


Ответы (9)


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

person Jeff Storey    schedule 07.10.2009
comment
Я думал об этом. иметь некоторый интерфейс C, который принимает и возвращает массивы и оборачивает многие вызовы C++ (и создает/уничтожает объекты). - person jb.; 08.10.2009
comment
почему это должен быть C, а не C++? - person Jeff Storey; 08.10.2009
comment
Я действительно ненавижу писать код C/C++, и если я использую интерфейс C, я смогу использовать JNA для подключения к C lib (а использование JNA означает отсутствие кода C :)) - person jb.; 08.10.2009

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

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

person Community    schedule 08.10.2009

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

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

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

person Sebastian    schedule 24.08.2015

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

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

person Denis Tulskiy    schedule 08.10.2009
comment
Спасибо за ссылку JAS3. Проблема в том, что физики-непрограммисты хотят ROOT. Но я постараюсь убедить их, что root не обязателен, и подумал, что его можно использовать через JNI. - person jb.; 09.10.2009

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

person Duck    schedule 07.10.2009
comment
Что ж, это пришло мне в голову, когда я нашел корневые привязки Python в моем репозитории Ubuntu. Если у меня будет выбор — Qt или Python, я выберу python. Но я буду придерживаться java (и, возможно, изучу python во время какого-нибудь небольшого проекта). - person jb.; 08.10.2009

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

person Wim Coenen    schedule 07.10.2009
comment
C# не настолько платформозависим. Мы выбираем Java, потому что есть некоторые другие функции (кроме того, что у нас есть несколько экспертов по Java;), например, нам нравится динамическое связывание (это позволяет нам очень легко включать плагины). - person jb.; 08.10.2009
comment
Mono — это кроссплатформенная реализация компилятора C# и платформы .NET. И, насколько мне известно, функции С# представляют собой надмножество java (за исключением проверенных исключений). Архитектуры плагинов в C# работают так же, как и в java (определение интерфейса плагина, загрузка и создание экземпляра плагина посредством отражения). - person Wim Coenen; 08.10.2009

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

person pfyon    schedule 08.10.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?). Сумма этих проблем (IMO) более значительна, чем время, необходимое для первоначальной разработки.

person Stephen C    schedule 08.10.2009
comment
Не могли бы вы рассказать о проблемах безопасности потоков, узнать о возможных проблемах с управлением памятью, но как насчет безопасности потоков? - person jb.; 08.10.2009

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

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

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

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

person Georg Fritzsche    schedule 08.10.2009
comment
Нет, с Qt у нас не все в порядке ;), но мы могли бы научиться :). Мы хотим иметь архитектуру плагинов, и я не знаю, как это сделать хорошо на C++. В java вы просто помещаете jar-файлы плагинов в каталог lib, классы вуаля доступны для вашего приложения. Также неплохо иметь одну бинарную версию для всех систем. - person jb.; 08.10.2009
comment
Но вам все равно нужно собрать ROOT и весь код-оболочку для каждой платформы, поэтому я не вижу преимущества. Кстати, Qt предоставляет вам структуру плагинов: doc.trolltech.com/4.5/plugins-howto. html - person Georg Fritzsche; 08.10.2009