Безопасно ли передавать объекты в функции C при работе в JNI Invocation API? - PullRequest
2 голосов
/ 29 апреля 2010

Я что-то кодирую, используя API вызова JNI. Программа на C запускает JVM и выполняет вызовы в нее. Указатель JNIenv является глобальным для файла C. У меня есть множество функций C, которые должны выполнять одну и ту же операцию с заданным классом задания. Поэтому я написал вспомогательные функции, которые берут задание и обрабатывают его, возвращая необходимые данные (тип данных C ... например, значение состояния int). Безопасно ли писать вспомогательные функции C и передавать им задания в качестве аргументов?

т.е. (простой пример - предназначен для иллюстрации вопроса):

int getStatusValue(jobject jStatus)
{
  return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);
}

int function1()
{
  int status;
  jobject aObj = (*jenv)->NewObject
    (jenv,
     aDefinedClass,
     aDefinedCtor);

  jobject j = (*jenv)->CallObjectMethod
    (jenv,
     aObj,
     aDefinedObjGetMethod)

  status = getStatusValue(j);

  (*jenv)->DeleteLocalRef(jenv,aObj);
  (*jenv)->DeleteLocalRef(jenv,j);

  return status;

} 

Спасибо.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2010

Все объекты jni действительны, пока не вернется нативный метод. Пока вы не храните неглобальные объекты jni между двумя вызовами jni, все должно работать.
Вызов функции jni должен работать так:

  1. вызов функции Java
  2. создание собственных локальных ссылок
  3. вызов собственной функции
  4. делай свое дело
  5. выход из нативной функции
  6. освободить существующие локальные ссылки
  7. возвращение в Яву

Шаг 4 может содержать любой код, локальные ссылки остаются действительными до шага 6, если не были выпущены ранее.
Если вы хотите хранить объекты jni на стороне c между двумя вызовами собственной функции java, вы должны создать глобальные ссылки и выпустить их позже. Отсутствие глобальной ссылки приводит к утечкам памяти, поскольку сборщик мусора не может освободить связанные объекты Java.

0 голосов
/ 29 апреля 2010

Я не знаком с деталями JNI, но однажды я заметил следующее:

return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);

Это похоже на официальный код JNI и принимает jobect в качестве параметра. Если это работает для JNI, нет никаких причин, по которым он не может работать для вашего кода.

...