1

是否JNIEXPORTJNICALL必须在实现 JNI 本机方法的函数声明中使用,该方法不是从动态库加载的,而是使用 JNI 函数注册的RegisterNatives

例如:

/* Is JNIEXPORT or JNICALL required here? */
JNIEXPORT void JNICALL test(JNIEnv *env, jobject obj) {
  /* ... */
}

JNINativeMethod method = {"test", "()V", (void*)test};
env->RegisterNatives(cls, &method, 1);

我的理解是这JNICALL是必需的,因为它指定了正确的调用约定,但JNIEXPORT不是必需的,因为它用于从动态库中导出函数。但是,我没有在 JNI 文档中找到确认。

4

1 回答 1

3

JNIEXPORT只需确保将标有它的函数添加到库的导出表中。这对于 JNI 的本地方法的自动链接是必要的,因为否则这些入口点(及其名称)将在链接时丢失,或者如果它们从未在代码中的其他地方使用,甚至可能被优化掉。JNICALL没有明确要求,只要求函数具有正确的调用约定。但是如果调用约定是正确的,如果方法指针指向可执行内存并且该地址的代码没有搞砸(异常,错误的调用约定,如果调用约定包括被调用者清理,则错误的参数,...) ,那么您可以使用任何方法指针,并且您不限于标有 的方法JNIEXPORT

资料来源:个人经历。我曾经写过一个库,它可以完全动态地创建和注册本机 JNI 方法存根,这些存根会将它们的参数收集到数组中,然后调用通用处理函数。

于 2013-07-02T17:20:35.087 回答