Соглашение о присвоении имен для метода интерфейса Java и имени модуля?
Я в состоянии следовать учебнику JNI просто отлично. Но когда я меняю имя метода, у меня возникают проблемы. Есть ли соглашение об именах, которому я должен следовать? В учебном пособии в качестве имени модуля и имени библиотеки использовался HelloJNI. Я использовал "useaaacom".
Я получил отличные отзывы об этом, и я делаю успехи. У меня есть связанный вопрос; дайте мне знать, если я должен создать еще один пост для него. Мне нравится строить на этом приложении, которое работает на данный момент. Как вызвать функции из драйвера устройства? У меня есть файл заголовка, и драйвер загружается в мое изображение. Под "как" я имею в виду, нужно ли мне иметь копию файла заголовка в моем проекте? Этот драйвер устройства реализован поставщиком, то есть он не является частью AOSP. У меня есть его копия, так как я скачал весь проект с открытым исходным кодом и собрал его. Так что я спрашиваю, что мне нужно в моем apk для приложения, чтобы вызвать функции, которые являются частью активного драйвера устройства?
Дайте мне знать, если я должен объяснить какую-либо часть этого больше, или мне нужно опубликовать файл заголовка или....
Я уже подтвердил, что могу открыть драйвер устройства со следующими строками кода:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
/* Our file descriptor */
int fd;
int rc = 0;
char *rd_buf[16];
printf("%s: entered\n", argv[0]);
/* Open the device */
fd = open("/dev/hello1", O_RDWR);
if ( fd == -1 ) {
perror("open failed");
rc = fd;
exit(-1);
}
printf("%s: open: successful\n", argv[0]);
/* Issue a read */
rc = read(fd, rd_buf, 0);
if ( rc == -1 ) {
perror("read failed");
close(fd);
exit(-1);
}
printf("%s: read: returning %d bytes!\n", argv[0], rc);
close(fd);
return 0;
}
Я думаю, что мне нужно добавить приведенный выше код в мою папку jni в виде исходного файла.c и вызвать функции из файла заголовка моего драйвера устройства из этого файла? Возможно, вы заметили, что приведенный выше код предназначен для драйвера тестового устройства с именем "hello1". Я собираюсь изменить имя на мой целевой драйвер устройства.
2 ответа
Динамические компоновщики разрешают записи на основе их имен. Собственное имя метода объединяется из следующих компонентов:
- префикс
Java_
- искаженное полное имя класса
- подчеркивание (
_
) разделитель- искаженное имя метода
- для перегруженных нативных методов два подчеркивания (
__
) с последующей искаженной подписью аргумента
Так что если у вас есть следующее:
package com.foo.bar;
class Baz {
public native void Grill(int i);
}
Тогда соответствующая функция C должна быть:
JNIEXPORT void JNICALL Java_com_foo_bar_Baz_Grill(JNIEnv *env, jobject thiz, jint i);
Если у вас есть подчеркивание в имени метода Java:
public native void A_Grill(int i);
Тогда функция C будет:
JNIEXPORT void JNICALL Java_com_foo_bar_Baz_A_1Grill(JNIEnv *env, jobject thiz, jint i);
_1
escape-последовательность соответствует _
в A_Grill
,
Вы можете вызывать ваш пакет, класс и методы как угодно на уровне Java в соответствии с правилами языка, но соглашение об именах на уровне C полностью определяется выходными данными javah
инструмент.
Вы можете вызывать разделяемую библиотеку как угодно, в зависимости от правил имен файлов и правил 'System.load()/loadLibrary()`.