2013-03-01 3 views
22

я нашел интересную feature в НКУ документации для C++:ехЬегпа «Java» блок в НКУ

java_interface атрибута

Этого типа информирует C++, что класс является интерфейсом Java. Он может применяться только к классам, объявленным в блоке extern «Java». Вызовы методов, объявленных в этом интерфейсе, будут отправляться с использованием интерфейса таблицы интерфейса GCJ, а не обычной отправки виртуальной таблицы.

Как я понимаю, это будет выглядеть примерно так:

extern "Java" { 
    class NativeClass __attribute__((java_interface)) { 
     //Implementation on native methods goes here. 
    } 
} 

Кто-нибудь знает подробности об этом? Как назвать методы NativeClass с Java? Может быть, кто-нибудь пробовал это в реальной жизни?

+1

Вы считали [googling 'gcj'] (https://www.google.com/search?clientrls=en&q=gcj&ie=UTF-8&oe=UTF-8)? – zneak

+0

GCJ - компилятор GNU для Java. Таким образом, возможно, это справедливо для байт-кода, скомпилированного только GCJ. В любом случае, интересно, работает ли он без JNI. – Ihar

+6

Он работает только с GCJ. В принципе никто не использует GCJ, так что это не имеет большого значения. – duskwuff

ответ

4

GCJ предоставляет два интерфейсов для Java: JNI с использованием C и CNI с использованием C++. Поскольку приведенный вами пример использует класс, он должен ссылаться на последний. В документе CNI documentation on interfaces описано только, как получить доступ к интерфейсам, описанным в Java, из кода на C++. Ваш пример, похоже, работает наоборот: класс, написанный на C++, который доступен из Java и служит в качестве интерфейса Java.

Но есть достаточно немного подробностей об этом, поэтому проб и ошибок будет один из способов экспериментировать с этим, и смотреть на реальные источники GCC будет другим.Если вы хотите увидеть один пример блока extern "Java" и атрибута java_interface, взгляните на java/lang/Readable.h. Он содержит представление C++ интерфейса Java java.lang.Readable. Как сказано в первой строке этого файла, он генерируется машиной. Поэтому, вероятно, причина, по которой так мало документации, заключается в том, что вы не должны сами писать это. Это просто деталь того, как GCJ реализует CNI. И, глядя более внимательно на вышеупомянутый файл, кажется, что они даже нарушают собственную документацию, поскольку этот Readable.h имеет атрибут вне блока extern, в отличие от фрагмента, который вы цитировали.

+0

Thanx, MvG. Вы прояснили все – Ihar

-1

Первый раз, когда я встретил этот тип блока, это было не для «java», а «C», поэтому я думаю, что это тот же интерес. Блок, определяемый:

extern "Java" 
{ 
// some java definition 
} 

предназначен для указания GCC, что этот блок является интерфейсом java Это используется для описания того типа манипуляции, который используется для определения класса. Название mangling - это использование gcc для генерации имени функции по параметрам и т. Д. Подробнее ... http://www.agner.org/optimize/calling_conventions.pdf Итак, вы используете extern "Java", когда вы импортируете код Java с ним, вы можете называть его juste, как любая функция в C/C++ без спецификаций исковерканное имя. Мое единственное использование этого было для dll с некоторыми функциями C, определенными в, загруженными в код на C++, поэтому я использую extern «C» для указания GCC, что определение этой функции не использует управление именами. Ну, теперь как вызвать собственный метод в java, потому что все в java - это метод, все - объект, функции нет. Во-первых, вы должны описать свой класс в java, все ваши функции, которые вы хотите сделать в native langage, должны быть определены как native: private native void print();. Во-вторых, обратно в свой родной заголовке кода, вы должны определить метод следующие номенклатуры:

extern "Java" 
{ 
     JNIEXPORT YourReturnType JNICALL Java_ClassName_MethodName (JNIEnv* env, jobject obj); 
} 

По крайней мере, все метод должен выглядеть так, вызвать JNI пошлет указатель JNIEnv и объект, который будет «это «в методе, если у вас есть другие аргументы, они должны быть предоставлены после двух основ. И, наконец, вы просто должны реализовать весь метод в родном файле кода, всегда после Нормативы, как:

JNIEXPORT void JNICALL Jave_Printer_print(JNIEnv* env, jobject obj) 
{ 
     printf("Hello world"); 
} 

Теперь вы можете создать объект принтера в Java и вызвать метод печати определяется как родной. Надеюсь, я ответил на ваш вопрос.

+0

Я знаю о ** extern "C" ** вызовах. Но Java отличается. Это требует, по крайней мере, JNI для вызова собственных функций (а не методов!). И я не понимаю, как вызвать код в этом блоке из JAVA – Ihar

+0

Извините, я не понимаю, что вы хотите, как это, поэтому я отредактировал, добавив некоторый намек на вызов метода в java, но я думаю, что в Java нет функции – Hulor

+0

Я твердо верю, что речь идет не о JNI вообще, а о CNI. См. Мой ответ для деталей. В этом случае большая часть вашего ответа ведет в неправильном направлении. – MvG

Смежные вопросы