Обертывание C / C ++ внутри Java - PullRequest
13 голосов
/ 12 января 2011

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

Я имею в виду, я хотел бы обернуть весь мой код C ++ (который уже разработан) в класс Java.Но не знаю, как это сделать.

Пожалуйста, опубликуйте ваши ответы или методы / шаги по интеграции C ++ в Java.(использование JNI - путь, но я не мог понять на www, как его использовать)

К вашему сведению, я использую Eclipse IDE для разработки.какие пакеты я должен включить в рабочую область моего проекта?

Ответы [ 8 ]

14 голосов
/ 02 марта 2011

Вместо JNI или JNI с некоторой помощью от автоматического генератора оболочек, такого как SWIG, или даже JNA, вы могли бы рассмотреть возможность разделения C / C ++ и Java на отдельные процессы и использование некоторой формы IPC и/ или Process абстракция Java для вызова программы, написанной на C / C ++.Этот подход отказывается от «обертывания», так что в некотором смысле это не ответ на этот вопрос, но, пожалуйста, прочитайте его перед повторным голосованием.Я считаю, что в некоторых случаях это разумный ответ на более широкий вопрос.

Причина такого подхода заключается в том, что когда вы вызываете C / C ++ непосредственно из Java, JVM подвергается рискулюбая ошибка в нативном коде .Риск зависит в некоторой степени от того, какой объем нативного кода принадлежит вам, и сколько вы ссылаетесь на сторонний код (и сколько у вас есть доступ к исходному коду такого стороннего кода).

Я выполнилв ситуации, когда мне пришлось вызывать библиотеку C / C ++ из Java, а в библиотеке C / C ++ были ошибки, которые вызывали сбой JVM.У меня не было стороннего исходного кода, поэтому я не мог исправить ошибки в нативном коде.Возможным решением было вызвать отдельную программу на C / C ++, связанную со сторонней библиотекой.Затем Java-приложение вызывало множество эфемерных нативных процессов всякий раз, когда ему было необходимо вызвать материал C / C ++.

Если у нативного кода есть проблема, вы можете восстановить / повторить в Java.Если нативный код обернут и вызван из процесса JVM, он может уничтожить всю JVM.

Этот подход влияет на производительность / потребление ресурсов и может не подходить для вашего приложения, но он того стоитрассмотрение в определенных ситуациях.

Наличие отдельного приложения, которое реализует функциональность кода C / C ++, потенциально полезно в качестве отдельной утилиты и для тестирования.А наличие чистого интерфейса командной строки или интерфейса IPC может упростить будущие интеграции с другими языками.

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

8 голосов
/ 12 января 2011

Если вы хотите вызвать C ++ из Java, вам нужно будет использовать JNI - собственный интерфейс Java.

Имейте в виду, что вы теряете некоторые преимущества сборщика мусора, поскольку он не может работать с вашими объектами C ++ и ваш код больше не будет переносимым.

Возможно, вам лучше научиться писать на 100% Java и оставить C ++ позади, но это всего лишь предложение.

5 голосов
/ 12 января 2011

Вы не можете «просто обернуть это», вам нужно написать немного клея на C / C ++.

Для начала, SWIG может сделать большую часть работы за вас.

3 голосов
/ 12 января 2011

Существует множество учебных пособий для того, чтобы делать именно то, что вы хотите. Например, проверить: http://www.javamex.com/tutorials/jni/getting_started.shtml

Есть также много предостережений от использования JNI. Я недавно начал работать с ним (просто для удовольствия, правда), и это, как правило, гораздо менее увлекательно, чем я ожидал.

Прежде всего, вам приходится иметь дело с загадочным кодом, таким как:

#include "test_Test.h"

JNIEXPORT jint JNICALL Java_test_Test_getDoubled(JNIEnv *env, jclass clz, jint n) {
    return n * 2;
}

Во-вторых, он имеет тенденцию преуменьшать одну из основных причин, почему вы используете Java в первую очередь: WORA («Один раз напиши», «Запусти где угодно»). Как упоминал Даффимо, могут быть проблемы с сборщиком мусора, но я думаю, что в последние годы JVM стала довольно умной в интеграции JNI.

С учетом вышесказанного, чтобы перенести весь ваш код C ++ в JNI, вам потребуется реорганизовать ваши интерфейсы (и, возможно, даже выполнить некоторую внутреннюю гимнастику). Это не невозможно, но это действительно не рекомендуется. Идеальное решение - просто переписать ваш код на Java.

С учетом вышесказанного, вы также можете "конвертировать" ваш код из C / C ++ в Java программно, и существует множество таких утилит. Но, конечно, машины глупее людей, и они также должны совершать ошибки, в зависимости от сложности вашего класса.

1 голос
/ 04 марта 2011

Вы можете писать код C ++ через JNI, но прямого преобразования классов C ++ в классы Java нет. Я использовал JNI для исправления проблем, обнаруженных в Android SDK (в частности, невероятно медленная реализация FloatBuffer.put), и я могу использовать его для некоторых критических областей производительности. Я бы посоветовал вам использовать его экономно и аккуратно, делать критичные для производительности вещи и уходить, не занимая при этом никакого выделения памяти, если вы можете помочь. Кроме того, не забудьте измерить ваш код, чтобы увидеть, действительно ли он быстрее.

Из интереса, для какой платформы вы разрабатываете? Единственной платформой, на которой имеет смысл обернуть большую часть кода C ++ в легкий слой Java, будет Android - на других платформах, просто скомпилируйте в C ++ и покончите с этим.

1 голос
/ 12 января 2011

Я бы избегал JNI, потому что писать утомительно, многословно и просто в целом. Вместо этого я бы использовал библиотеку JNA, которая делает написание нативной интеграции настолько простым.

https://github.com/twall/jna/

Удачи.

0 голосов
/ 02 марта 2011

BridJ был специально разработан для этого (и поддерживается JNAerator , который будет анализировать ваши заголовки C / C ++ и выдавать вам привязки Java).

Это недавняя альтернатива JNA с поддержкой C ++.

0 голосов
/ 12 января 2011

JNI модуль не является классами Java.Это C. Использование JNI сопряжено со многими ограничениями, и некоторая среда Java плохо поддерживает JNI.

Не поддерживается поддерживаемый способ «обернуть мой код C ++ в класс Java» (EDIT: Iзначит, без JNI в настоящее время, но JNI проблематичен.)

Вы могли бы исследовать пользовательский компилятор C ++, генерирующий Java-байтовые коды, но никто (включая меня) не будет рекомендовать этот подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...