Jimmy Chen

A Programmer

(原创) JNI编程指南与规范 第二章 内容补充

第二章 内容补充

  在原文中,构建JNI程序的方法只介绍了一个,其实构建JNI程序还有另外一种方法,这种方法我们称之为动态注册,相对的之前的方法我们称之为静态注册。我们先将方法介绍后,再看一下这两种方法有什么区别。

  从一个例子出发,例子和第二章的例子一样,也是在Java中调用一个native方法打印出“Hello World!”的字样。Java侧的代码如下:

  代码意思都是一样的,都是在HelloWorld类的main方法中创建一个对象,然后调用native层的方法HelloWorld来打印字符串。下面部分是native层的代码:

  • 首先要介绍的是JNI_OnLoad方法,这个方法是自动调用的,在Java侧,我们在静态代码块内通过System.loadLibrary,加载动态库的时候,相应的动态库的JNI_OnLoad方法就会自动执行。
  • 在JNI_OnLoad方法中,带有的参数是JavaVM而不是我们常见的JNIENV,所以需要向获取到JNIEnv对象,然后我们通过JNIEnv的FindClass方法找到我们需要动态注册的类。
  • 最后我们通过RegisterNatives方法,将gMethods数组中的Java层的函数和native层的函数动态绑定起来。

  其中JNINativeMethod是一个结构体,定义如下:

  name指的是Java中定义的方法, signature指的是方法的描述符,也可以叫做签名,“()V”中“()”表示的是方法的参数为void,“V”表示的是返回值为void,具体的定义在第四章会讲到,这里可以先跳过。fnPtr指向的是native的方法名。

  最后按照第二章中介绍的方法,编译运行就可以了。

  动态注册和静态注册相比,动态注册更加灵活而且简单,不像静态注册那样,还需要用java和javah编译后才得出最后的函数名,如果中间Java文件改动,添加了native方法或者修改了native方法的函数名,又要重新做上面的步骤,麻烦。看过Android源码的朋友都应该发现了,Android中的JNI相关内容几乎都是用动态注册方法的。

此文为博主原创文章,转载请注明出处

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注