Одним из способов регистрации собственных функций в JNI является использование функции RegisterNatives()
. Пример (хотя и с некоторыми ошибками) можно найти в Android документации здесь . Вот пример кода, демонстрирующий эту технику:
#include <jni.h>
void JNICALL test(JNIEnv* const environment, jobject const objectOrClass) {
}
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* const vm, void* const reserved) {
JNIEnv* environment;
vm->GetEnv(reinterpret_cast<void**>(&environment), JNI_VERSION_1_6);
auto const classRef = environment->FindClass("com/example/test/MainActivity");
JNINativeMethod method;
method.name = "test";
method.signature = "()V";
method.fnPtr = reinterpret_cast<void*>(test);
environment->RegisterNatives(classRef, &method, 1);
return JNI_VERSION_1_6;
}
Использование RegisterNatives()
требует, чтобы указатели на функции (не являющиеся членами) указывали на void*
, как показано выше. Согласно этой документации , это не обязательно переносимо в C ++. Может быть гарантированно работать в некоторых средах (например, POSIX), но в остальном поведение зависит от реализации.
Я бы не ожидал, что эта функциональность будет раскрыта таким образом, если она ненадежна, но JNI или Android предлагают какие-либо гарантии того, что на это можно рассчитывать? Предполагается ли, что JNI и / или Android всегда будут работать в средах, где поддерживается приведение между указателями на функции и void*
?
РЕДАКТИРОВАТЬ:
После дальнейшего рассмотрения кажется, что JNI почти придется делать что-то непереносимое по отношению к нативным функциям, независимо от проблемы приведения. Единственной информацией о функции, которую имеет JNI (кроме адреса), является строка, описывающая аргументы и возвращаемые типы, поэтому маловероятно, что void*
когда-либо будет приведен обратно к действительному указателю на функцию и использован обычным способом. Предположительно, вместо этого вызовы выполняются с помощью низкоуровневого кода c, определяемого платформой.
По-прежнему кажется необходимым, чтобы функция-указатель на void*
приводила себя хорошо, поэтому, если кто-то знает, если или как JNI гарантирует это, мне все равно было бы интересно узнать.