Подтвердить что ты не робот

Что делает метод registerNatives()?

В java, что делает частный статический метод registerNatives() класса Object?

4b9b3361

Ответ 1

Другие ответы технически правильны, но не очень полезны для тех, у кого нет опыта JNI.: -)

Обычно для того, чтобы JVM мог найти ваши собственные функции, их нужно назвать определенным образом. например, для java.lang.Object.registerNatives, соответствующая функция C называется Java_java_lang_Object_registerNatives. Используя registerNatives (вернее, функцию JNI registerNatives), вы можете называть свои функции C тем, что вы хотите.

Здесь соответствующий C-код (из OpenJDK 6):

static JNINativeMethod methods[] = {
    {"hashCode",    "()I",                    (void *)&JVM_IHashCode},
    {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},
    {"notify",      "()V",                    (void *)&JVM_MonitorNotify},
    {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},
    {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
};

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

(Обратите внимание, что Object.getClass отсутствует в списке, он все равно будет вызываться "стандартным" именем Java_java_lang_Object_getClass.) Для перечисленных функций соответствующие функции C указаны в этой таблице, что чем писать кучу функций переадресации.

Регистрация собственных функций также полезна, если вы встраиваете Java в свою C-программу и хотите связать себя с функциями внутри самого приложения (в отличие от общей библиотеки), или используемые функции не иначе "экспортируются", так как они обычно не будут найдены стандартным механизмом поиска метода. Регистрация собственных функций также может быть использована для "повторной привязки" собственного метода к другой функции C (полезно, если ваша программа поддерживает динамическую загрузку и выгрузку модулей, например).

Я призываю всех прочитать книгу JNI, в которой говорится об этом и многом другом.: -)

Ответ 2

Что может быть немного запутанным, так это то, что код, показанный для java.lang.Object.registerNatives в предыдущем ответе, является просто примером регистрации собственных функций. Это код, который (в реализации OpenJDK) регистрирует собственные функции для класса Object. Чтобы зарегистрировать собственные функции для своего собственного класса, вы должны вызвать функцию JNI RegisterNatives из собственного кода в вашей собственной библиотеке. Это может показаться немного круговым, но есть несколько способов разбить цикл.

  • Следуйте примеру этой реализации класса Object:

    а. В вашем классе Java объявите собственный метод (желательно статический) с именем RegisterNatives (или любым другим именем, это не имеет значения).

    б. В вашем собственном коде определите функцию с именем Java_<your fully qualified class name>_registerNatives, которая содержит вызов функции JNI RegisterNatives.

    с. Убедитесь, что в вашем Java-коде метод Java RegisterNatives вызывается перед любыми вызовами других собственных методов.

ИЛИ

  1. Используйте JNI_OnLoad

    а. В вашей собственной библиотеке определите функцию jint JNI_OnLoad(JavaVM *vm, void *reserved). В теле этой функции вызовите функцию JNI RegisterNatives.

    б. Java VM автоматически ищет и вызывает JNI_OnLoad, когда ваша родная библиотека загружается System.loadLibrary, которую вы уже должны вызывать, возможно, в статическом инициализаторе для вашего класса. (Вы получаете требуемый указатель env, вызывая функцию GetEnv в таблице, на которую указывает указатель vm.)

Ответ 3

Поскольку вы искали исходный код, чтобы его найти, довольно легко догадаться, не так ли?

Это собственный метод, и он называется registerNatives, поэтому я предполагаю, что он регистрирует объекты с базовой платформой.

Он также закрыт, поэтому его, вероятно, не беспокоит.