1

In the code sample for accessing via "C", the env pointer is used like:

const char *str = (*env)->GetStringUTFChars(env, s, 0);

While for C++, the sample makes the same call:

const char *str = env->GetStringUTFChars(s, 0); 

The document goes on to say:

With C++, the extra level of indirection and the interface pointer argument disappear from the source code. However, the underlying mechanism is exactly the same as with C. In C++, JNI functions are defined as inline member functions that expand to their C counterparts.

Does that statement mean that the C++ version would eventually expand to the C version and have the same level of indirection?

I haven't looked at the header files, but I'm puzzled. Can someone explain this difference?

4

3 回答 3

4

问题中引用的解释解释了它。C++ 支持内联成员函数,但 C 不支持。的 C++ 定义JNIEnv包括 C 定义不包含的函数定义。C++ 定义如下所示:

char const* JNIEnv::GetStringUTFChars(jstring s, jint i)
{
  return (*this)->GetStringUTFChars(this, s, i);
}

C 版本中调用的函数实际上是一个函数指针。本质上,aJNIEnv*是一个 vptr,指向一个带有一堆 JNI 提供的函数指针的结构。为了方便, C++ 中直接提供了额外的定义JNIEnv,以避免重复this函数调用的参数。

于 2013-01-17T22:59:36.387 回答
3

我还没有检查他们是如何实现它的,但我很有信心它是这样的:

  • 在 C++ 中,JNIEnv* 将是方法的“this”,这使得方法也可以使用 env 指针
  • 在 C 中,函数(结构中的函数指针指向的)可以使用它的唯一方法是,如果有人将它作为参数传递。
于 2013-01-17T22:55:43.207 回答
1

因此,查看OpenJDK 源代码,jni.h 在标头中有以下内容:

770 /*
771  * We use inlined functions for C++ so that programmers can write:
772  *
773  *    env->FindClass("java/lang/String")
774  *
775  * in C++ rather than:
776  *
777  *    (*env)->FindClass(env, "java/lang/String")
778  *
779  * in C.
780  */
781 
782 struct JNIEnv_ {
783     const struct JNINativeInterface_ *functions;
784 #ifdef __cplusplus
785 
786     jint GetVersion() {
787         return functions->GetVersion(this);
788     }

感谢大家澄清这一点。

于 2013-01-18T00:21:21.157 回答