JNI: от кода C до Java и JNI

Задний план

Я разрабатываю приложение для 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 я использую 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 Code?
  • Что я должен написать в JAVA-коде вместо unsigned char data[1]; ?

Вопрос 2.

  • Как я могу использовать class jblobData_c вместо blobData_t* pInputInfo в 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. Прохождение большой структуры С через JNI эффективно
  3. Возвращение объекта структуры с C на Java через JNI
  4. Передача данных между Java и C
  5. Передача указателя из JNI на Java с использованием длинного
  6. Передача указателей между C и Java через JNI

Solutions Collecting From Web of "JNI: от кода C до Java и JNI"

По вопросу № 1:

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

 char c_char = (char)java_char; 

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

По вопросу № 2:

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

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

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

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