У меня есть проект, записанный в C++, и я надеюсь писать Java GUI как интерфейс к нему. Выбор Java фиксируется так, я должен был бы изучить, как смочь назвать код C++ от Java. Перезапись кода C++ не является опцией. Я хотел бы вход на:
Спасибо.
Скомпилируйте графический интерфейс с помощью GCJ и используйте CNI для обертывания кода C ++. См. http://gcc.gnu.org/java/faq.html#6_2 для некоторых сравнительных примеров использования CNI по сравнению с JNI (что вы бы использовали со всеми другими средами выполнения Java).
Предполагается, что CNI будет намного проще, чем JNI.
Я бы выбрал некоторую форму IPC (каналы, возможно, даже сокеты). Таким образом, ваш код сводится к копированию в байтовые массивы и из них в C ++, а также к использованию InputStreams и OutputStreams в Java.
Недавно я работал над проектом, в котором у нас была библиотека, распространяемая сторонняя программа, написанная на C ++. Но каждая система у нас есть мог бы использовать эту библиотеку был написан на Java.
Мы пошли по пути упаковки библиотеки как собственного исполняемого файла, который читает ввод из stdin, переводя его в вызовы функций в библиотека. Соответственно, результаты из библиотеки были конвертированы и напечатано в стандартный вывод.
Это также означало, что оболочку было легко протестировать, поскольку все, что мне нужно было сделать был вызван из командной строки. Обнаружено множество ошибок и проблем. из-за этого. Тщательно рекомендую это.
Следующей проблемой было «Как мне вызвать оболочку C ++» и «Как мне упаковать его в приложение Java »? На самом деле мы избегали ответов на эти вопросы, выставив исполняемый файл через inetd. Итак, наша java приложения вызывали код C, открывая сокет. Потому что я закодировал оболочка для связи через stdout и stdin, мне не нужно было изменять это вообще , чтобы открыть его через TCP (читайте inetd , если вы озадачены). Самая изящная часть программирования, которую я когда-либо делал ...: -)
Извините, я зашел в обход.Я пытался проиллюстрировать гибкость, которую вы можете получить, если решите разделить код C ++ на отдельный процесс. Дело в том, что вы выполнили работу по сортировке ваши структуры данных заранее. Так что сначала вы можете оставить свой другой обрабатывать локально и связываться с ним через канал. Дело в том, что если вы когда-нибудь решите, что вам нужно отправить запросы на удаленный TCP-сервер, изменение java-программы не потребует больших усилий. У тебя есть уже проделала большую часть работы. Возможно, стоит подумать. Не знаю, подходит ли он вам на самом деле.
Я не использовал JNI, но у нас есть приложения, которые используют его на работе, и все они страдают от проблем с управлением памятью:
1) Если код C / C ++ ошибается с арифметикой указателей, ваш Java приложение тоже облажалось. Вероятно, он умрет с SIGSEGV. Так что ваши Код C / C ++ должен быть надежным, хорошо протестированным и заслуживающим вашего доверия. С проект, над которым я работал, большинство приложений Java были серверными процессами, которые должны работать 24/7. Мы не доверяли этой третьей стороне библиотека , которая очень полезна, как бы она ни была.
2) Передача структур данных между Java и C ++ может быть затруднительной. Особенно, если вы передаете объекты Java в функции C. Вы обычно необходимо выполнить какое-то преобразование, что вызывает такие проблемы, как 'следует ли мне копировать эту структуру данных? Когда мне его уничтожить? Это особенно плохо, если вы непреднамеренно назовете "бесплатно" какой-то объект, который был выделены в программе Java.
3) Я видел код JNI. Просто выглядит некрасиво ... [barf]
Простите за длинный пост.
Недавно я работал над проектом, в котором нам нужно было сделать точно такую же вещь. У нас была модель данных, написанная на C++, и нам нужно было сделать графический интерфейс на Java. В итоге мы определили классы C++, к которым нам нужно было получить доступ из GUI, и использовали SWIG для создания обычных старых классов java, которые обернули объекты C++.
Java-классы, созданные SWIG, имеют идентичные интерфейсы с C++ классами, которые они оборачивают, что означает, что взаимодействие с C++ объектами из Java подразумевает только работу с Java объектами.
Вот пример:
Даны два класса C++:
class SomeClass {
public:
void foo(SomeOtherClass bar);
SomeOtherClass baz();
}
class SomeOtherClass {
public:
void do();
}
SWIG сгенерирует два класса Java:
public class SomeClass {
public void foo(SomeOtherClass bar);
public SomeOtherClass baz();
}
public class SomeOtherClass {
public void do();
}
Вызов объектов C++ из Java - это все равно, что писать на обычном Java:
SomeClass sc = new SomeClass();
SomeOtherClass soc = sc.baz();
sc.foo(soc);
Строка 1: Инстанцируется Java-обертка SomeClass, а также C++ объект типа SomeClass.
Строка 2: Вызовы к sc экземпляру SomeClass передаются экземпляру SomeClass в C++. Возвращаемое значение экземпляра C++ передается в Java-обертку и возвращается Java-оберткой.
Строка 3: SWIG обрабатывает преобразование типов Java-обертки (или примитивных типов java) в базовые типы C++.
SWIG позаботится о преобразовании в/из Java/C++ типов во время вызовов методов, и все детали JNI будут скрыты от глаз :)
Код интерфейса SWIG, необходимый для создания Java-обертки для класса C++, может быть таким простым:
interface.i: { #include "ClassDefinition.h" } %include "ClassDefinition.h"
SWIG очень мощный. Все, что вам нужно сделать, вы можете сделать либо с помощью базовых возможностей, типовых карт, карт типов javacode, либо с помощью режиссеров.
SWIG также позволяет вашему коду C++ вызывать объекты Java без каких-либо изменений в существующем коде C++. Это функция называется "кросс-языковой полиморфизм". Кросс-языковой полиморфизм позволяет создавать классы Java, которые являются подклассами классов C++. Затем вы можете передавать экземпляры этих классов Java в качестве параметров в вызовы методов C++. Любые вызовы из C++ для переданного экземпляра будут перенаправлены обратно к вашему Java-объекту. Я не буду вдаваться в подробности, но это не так уж сложно, как только вы преодолеете первоначальный шок от этой идеи.
JNI
JNA
Оба они не зависят от платформы. Я предпочитаю jna, потому что код jni легко испортить. Также существует несколько решений, зависящих от платформы, но я не очень хорошо их знаю.
В зависимости от того, насколько тесно интерфейс должен быть связан с кодом C ++, проще всего было бы запустить графический интерфейс и код C ++ как отдельные программы, которые обмениваются данными через какой-то IPC (сокеты, именованные каналы в Unix и т. д.)
Другая альтернатива, о которой я слышал, но так и не реализовал, - это создание оболочки JNI (собственный интерфейс Java) вокруг вашего кода C ++. Судя по тому, что у меня в голове, это непростое упражнение.