JNI: от кода C до Java и JNI - PullRequest
11 голосов
/ 02 июня 2011

Фон

Я разрабатываю приложение для Android в Eclipse, и теперь у меня есть проблема, и мне нужна ваша помощь.Поэтому я должен вызвать функцию, написанную в C из приложения JAVA.Но на моем пути написания кода у меня есть Вопросы , которые вы можете увидеть ниже.Я жду ваших ответов и идей ...

C Код:

typdef struct blobData_s {
    unsigned long length;
    unsigned char data[1];
} blobData_t;

unsigned int CheckEnrollmentExist ( unsigned long hdevice, blobData_t* pInputInfo ) {
    // Function code goes here
    ..........................
    return some_value;
}

Код JAVA:

В коде JAVA вместо unsigned long Iиспользуйте int, чтобы я мог писать.

class jblobData_c {
    public int langth;
    *Question 1.*
}

public class ApplicationMainClass extends Activity {
    // Some code goes here
    ......................

    public native int JCheckEnrollmentExist( int jhdevive, *Question 2.* );

}

Вопрос 1.

  • Что я могу использовать вместо unsigned char в коде JAVA?
  • Что я должен написать в коде JAVA вместо unsigned char data[1];?

Вопрос 2.

  • Как яможно использовать class jblobData_c вместо blobData_t* pInputInfo в коде JAVA?
  • Что я должен написать в JAVA вместо blobData_t* pInputInfo?

Код JNI:

JNIEXPORT jint JNICALL Java_com_Test_JCheckEnrollmentExist(JNIEnv* env, jobject obj, jint jhdevice, *Question 2.* ) {

    // Call the base function from C code.
    return CheckEnrollmentExist( jhdevice, *Question 3.*);
}

Вопрос 3.

  • Что я должен написать в функции CheckEnrollmentExist, которая является функцией кода C вместо blobData_t* pInputInfoчтобы эта функция работала правильно, а заданный параметр был одинаковым

Ссылка

  1. Как передавать структуры C вперед и назад в Javaкод в JNI?
  2. Эффективное прохождение большой структуры C через JNI
  3. Возвращает объект структуры из C в Java через JNI
  4. Передача данных между Java и C
  5. Передача указателя из JNI в Java с использованием long
  6. Передача указателей между C и Java через JNI

1 Ответ

2 голосов
/ 02 июня 2011

Для вопроса № 1:

Вы можете использовать jchar.Примитивные символы в java не подписаны, это единственный примитив, который не подписан.Обратите внимание, что jchar - это символ UTF-16, поэтому вам придется «сопоставить» jchar с обычным символом, как это было бы в случае с любой проблемой преобразования символов.Для простых преобразований это обычно может быть сделано путем приведения

char c_char = (char)java_char;

, поскольку ядро ​​ASCII разделяет одинаковые числовые значения между ASCII и UTF-16.Однако это может привести к ошибкам, если кто-нибудь попытается передать «специальный» символ через интерфейс.Гораздо лучшим способом было бы (на стороне java, поскольку это проще) преобразовать символы в байты, используя соответствующий набор символов для вашей платформы (для обеспечения совместимости платформы в слоях C).Тогда вам нужно всего лишь передать байт [] в вызов JNI, и байты будут правильно соответствовать символам, которые, вероятно, ожидает C.

Для вопроса № 2:

Если ваш метод CheckEnrollmentExists(...) является точкой входа привязки JNI, вы не можете безопасно изменять типы данных.Это означает, что все входные данные должны быть значениями типа данных JNI.Хотя вы можете выбирать эквиваленты типов данных C (и вы все равно можете заставить свой компилятор делать это), такие методы следует не одобрить.Это неявно означает, что точки входа JNI не могут принимать структуру данных структуры, не определенную в заголовках JNI.Другими словами, вы не можете передать свою собственную структуру методу.

Если метод требует доступа к структуре C через вызовы, используйте другое средство.Я видел, как люди хранят указатель на выделенную структуру данных в виде целого или длинного члена (при правильном приведении).Затем вы можете переписать часть собственного кода, чтобы получить указатель от объекта «this», передаваемого в вызов, и выполнить разыменование для получения необходимых данных.

For Question #3:

Это фактически то же самое, что и вопрос № 2.В «связывающую обертку», которую вы поместили, вы должны извлечь сохраненное значение указателя в поле int или long объекта java, привести его к соответствующему указателю структуры и затем передать его внутреннему методу.Поскольку передача указателя является вызовом C на C, никакой дополнительной магии не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...