Продолжается подписка на наши издания! Вы не забыли подписаться?

Совместное использование Java и C++**

Петр Михеев

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

Язык Java был создан на основе языка С++, у которого были позаимствованы синтаксис и базовая семантика. В Java используются практически идентичные соглашения для объявления переменных, передачи параметров, операторов и для управления потоком выполнением программы. В Java были добавлены все хорошие черты C++, но исключены некоторые недостатки последнего. Например, оператор goto, глобальные переменные и ненадежное приведение типов. Более того, Java полностью объектно-ориентированный язык. Однако все это привело к уменьшению быстродействия программ, невозможности напрямую использовать системные ресурсы, а также к некоторым другим проблемам. Сегодня возможностей языка Java и его стандартных библиотек классов вполне достаточно для написания различных полнофункциональных приложений. В Java JDK входит множество библиотек классов, в которых есть все, начиная от классов ввода/вывода и кончая классами для распределенного программирования. Но бывают случаи, когда программисту необходимы возможности, не поддерживаемые Java, но имеющиеся в С++. Например, использовать ресурсы конкретной операционной системы, взаимодействовать с различными аппаратными устройствами, пользоваться уже существующим, написанными не на Java кодом, или создавать программы реального времени. Для этого в Java есть интерфейс, который используется для вызова функций, написанных на других языках. Сегодня такой интерфейс существует только для языка С++. Механизм языка Java используемый для вызова кода, написанного на других языках, называется JNI (Java Native Interface). JNI – это прикладной интерфейс программирования (API – Application Programming Interface), который позволяет вызывать “родные” или “native” (т.е. написанные для определенного процессора) методы из приложений на языке Java. С другой стороны, используя возможности JNI, ваши родные методы могут создавать и использовать объекты Java. Они могут вызывать методы классов, динамически определять типы структур данных, перехватывать и возбуждать исключения, загружать классы и получать о них различную информацию. Таким образом, все возможности, которые используются в приложениях на языке Java, можно использовать и в родных методах. В состав JNI входит Invocation API, который позволяет приложениям динамически загружать виртуальную машину Java (Java Virtual Machine – JVM). Это позволяет легко встраивать возможности Java в существующие системы без необходимости их статического связывания с кодом виртуальной машины.

Возможность взаимодействовать с программами, написанными на других языках, очень важна, так как обеспечивает возможность расширения языка Java. Например, применяя интерфейс JNI, вы можете выполнить на языке С++ определенные функции, недоступные в Java, скажем, системные вызовы. Вы можете использовать уже написанные программы на С++, а также имеющиеся библиотеки функций. Может случится так, что программисту понадобятся конструкции, отсутствующие в Java, например, указатели в С++.

Но с другой стороны есть и серьезные аргументы против такого подхода. Во-первых, Java с самого начала создавался как язык, обеспечивающий повышенную безопасность. Методы, написанные на других языках, могут обойти систему безопасности Java. Например, используя указатели, можно беспрепятственно получить доступ к любым данным в памяти. При загрузке байт-кодов с сервера система управления безопасностью проверяет их, и гарантирует их безопасность до выполнения. С программами на языке С++ сделать такое практически невозможно. Поэтому некоторые браузеры и программы просмотра не поддерживают загрузку dll-файлов из соображений безопасности.

Во-вторых, главное достоинство языка Java – это переносимость на различные платформы. Методы, написанные на других языках, могут затруднить переносимость, так как их придется тестировать на множестве различных платформ

В-третьих, при разработке приложения на нескольких языках, появляется необходимость в синхронной поддержке компонентов, написанных на разных языках. Это гораздо труднее, чем согласовывать программные компоненты, написанные на одном языке.

Наконец, если апплет Java использует методы, написанные на других языках, то появляется проблема передачи dll-файлов методов на все компьютеры-клиенты, выполняющие этот апплет.

В этой статье мы рассмотрим Java Native Interface (JNI) - стандартный механизм вызова из Java-приложений кода, написанного других языках. Этот механизм существует в Java, начиная с версии 1.1. Он частично совместим со своим предшественником Native Method Interface (NMI), который использовался в Java версии 1.0.

Основным преимуществом JNI перед NMI и другими аналогичными интерфейсами (Netscape Java Runtime Interface, Microsoft's Raw Native Interface и COM/Java Interface) является то, что JNI обеспечивает совместимость приложений, написанных с использованием JNI, для любых JVM на конкретной платформе. Это значит, что один и тот же скомпилированный код С++ должен одинаково корректно выполняться виртуальными машинами Netscape Navigator, Microsoft Explorer и другими виртуальными машинами для конкретной платформы (например, Windows или Unix). NMI не удовлетворял этому требованию. Он использовал структуры С++ для доступа к полям объектов Java. Таким образом, код С++ зависел от того, как JVM располагает объекты в памяти. Следовательно, требовалась перекомпиляция соответствующего кода С++ для каждой JVM, используемой на данной платформе. Учитывая недостатки NMI, разработчики Java перестали его поддерживать, начиная с версии Java 1.1. По этой причине здесь мы его рассматривать не будем.

В следующих разделах мы рассмотрим, как вызывать функции С++ из Java-программ, как использовать объекты Java в программах на С++, а также, как с помощью Invocation API динамически создать JVM в программе на С++ и загрузить на выполнение произвольный класс...

Прочитать статью полностью вы можете в печатной версии журнала

Copyright © 1994-2016 ООО "К-Пресс"