Используя Java для обертывания по C++

У меня есть проект, записанный в C++, и я надеюсь писать Java GUI как интерфейс к нему. Выбор Java фиксируется так, я должен был бы изучить, как смочь назвать код C++ от Java. Перезапись кода C++ не является опцией. Я хотел бы вход на:

  1. Что инструменты могут я использовать для достижения этого обертывания.
  2. Сколько из кода C++ было бы, я должен обязательно изменить, если таковые имеются.
  3. Любое другое понимание/следовать подвергает сомнению, который Вы имели бы.

Спасибо.

11
задан sparkFinder 28 July 2010 в 18:34
поделиться

6 ответов

Вам следует искать JNI - собственный интерфейс Java

3
ответ дан 3 December 2019 в 06:19
поделиться

Скомпилируйте графический интерфейс с помощью GCJ и используйте CNI для обертывания кода C ++. См. http://gcc.gnu.org/java/faq.html#6_2 для некоторых сравнительных примеров использования CNI по сравнению с JNI (что вы бы использовали со всеми другими средами выполнения Java).

Предполагается, что CNI будет намного проще, чем JNI.

0
ответ дан 3 December 2019 в 06:19
поделиться

Я бы выбрал некоторую форму 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]

Простите за длинный пост.

2
ответ дан 3 December 2019 в 06:19
поделиться

Недавно я работал над проектом, в котором нам нужно было сделать точно такую же вещь. У нас была модель данных, написанная на C++, и нам нужно было сделать графический интерфейс на Java. В итоге мы определили классы C++, к которым нам нужно было получить доступ из GUI, и использовали SWIG для создания обычных старых классов java, которые обернули объекты C++.

http://www.swig.org/

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-объекту. Я не буду вдаваться в подробности, но это не так уж сложно, как только вы преодолеете первоначальный шок от этой идеи.

7
ответ дан 3 December 2019 в 06:19
поделиться

JNI

  • Если ваш код - c ++
  • JNI является частью среды выполнения java
  • объявите собственные функции и сгенерируйте заголовок ac / c ++ с помощью javah
  • напишите код c / c ++, чтобы приклеить ваш код к методы java

JNA

  • Если у вас есть ac api для вашего кода
  • не работает с классами c ++
  • JNA не является частью среды выполнения java, jna.jar составляет 300 КБ
  • объявить интерфейс java используя методы c, которые вы используете
  • , напишите java-код, чтобы связать вашу dll с java
  • , необходимо создать java-копию c-структур, используемых функциями dll

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

  • JACOB: java COM-мост (windows)
  • ...
5
ответ дан 3 December 2019 в 06:19
поделиться

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

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

2
ответ дан 3 December 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: