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

StackOverflow https://stackoverflow.com/questions/1534734

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

Всякий раз, когда вы вызываете код 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?).Сумма этих проблем (ИМО) более значительна, чем время, необходимое для первоначальной разработки.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top