欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

passes them to the Java method that the 次  来源:昆山软开发 时间:2018-10-09

原文出处: Young_Blog

JNI 全称是 Java Native Interface。是在 Java 和 Native 层(包罗但不限于C/C++)彼此挪用的接口类型。

JNI 在 Java 1.1中正式推出,在 Java 1.2版本中插手了 JNI_OnLoad、JNI_OnUnload 要领,这两个要领照旧很有用的,后头再说。

JNI基本篇

Java 通过 JNI 挪用当处所法的进程大抵是:

  1. 写一个 Java 类,在个中声明对应要挪用的 native 要领,用 native 要害字修饰。 好比 private static native int native_newInstance();
  2. 通过 javah 呼吁生成 Java 类对应的 C/C++ 头文件。javah -encoding utf-8 -cp src com.young.soundtouch.SoundTouch;
  3. 在 C/C++ 中实现头文件中声明的函数;
  4. 编译 C/C++ 代码为动态库(Windows中的dll、Linux/Android 中的 so、MAC OSX 中的 dylib);
  5. 在 Java 代码中加载动态库,即可像挪用 Java 要领一样,挪用到 native 函数。

个中第3步在 Java 1.2 中增加了 JNI_OnLoad 要领之后有另一种实现方法(后头说)。

javah 生成的头文件大抵是这样的:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_young_soundtouch_SoundTouch */

#ifndef _Included_com_young_soundtouch_SoundTouch
#define _Included_com_young_soundtouch_SoundTouch
#ifdef __cplusplus
extern "C" {
#endif
#undef com_young_soundtouch_SoundTouch_SETTING_USE_AA_FILTER
#define com_young_soundtouch_SoundTouch_SETTING_USE_AA_FILTER 0L
	/*
	* Class:     com_young_soundtouch_SoundTouch
	* Method:    native_getDefaultSampleElementSize
	* Signature: ()I
	*/
	JNIEXPORT jint JNICALL Java_com_young_soundtouch_SoundTouch_native_1getDefaultSampleElementSize
		(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif

文件开头就是普通的头文件,可是可以发明:

  1. 包括了 jni.h 头文件(一般位于 $JAVA_HOME/jd{jdk-version}/include 文目次内)。这是 JNI 中所有的范例、函数、宏等界说的处所。所以C/C++世界的JNI是由他拟定的游戏法则。
  2. 在类中生命的常量(static final)范例会在头文件中以宏的形式呈现,这一点照旧很利便的。
  3. 函数的注释照旧较量全的,包罗了:
  4. 对应的 class
  5. 对应的 Java 要领名
  6. 对应 Java 要领的签名
  7. 要领的声明明得有点奇怪,由以下及部门构成:
  8. JNIEXPORT这是函数的导出方法;
  9. jint 返回值范例(jint 由 jni.h 界说,对应 int,下面详细再说吧);
  10. JNICALL 函数的挪用方法也就是汇编级别参数的传入方法;
  11. Java_com_young_soundtouch_SoundTouch_native_1getDefaultSampleElementSize —— 超等长的函数名!!!名目是 Java_ + 类全名 + _ + JAVA 中声明的native要领名。个中会把包名中的点(.)替换成下划线(_),同时为了制止斗嘴把下划线替换成_1;
  12. 要领的参数,上面的这个要领在 Java 的声明中实际上是没有参数的,个中的 JNIENV 顾名思义是 JNI 情况,和详细的线程绑定。而第二个参数 jclass 其实是 Java 中的 Class。因为上面是一个 static 要领,因此第二个参数是 jclass。假如是一个实例要领例对应第二个参数是 jobject,相当于 Java中的 this。

下面在 C/C++ 中实现这个要领就行啦。可是在动手前现大抵相识以下 jni.h 拟定的游戏法则。

范例转换

javah 生成的头文件内里利用的范例都是 jni.h 界说的,目标是做到平台无关,好比担保在所有平台上 jint 都是32位的有标记整型。

根基对应干系如下:

 passes them to the Java method that the   <a href=劳务调派打点系统 programmer wishes to invoke.” CalltypeMethodA(jobject obj" class="size-full wp-image-30095 aligncenter" title="Snipaste_2018-10-08_07-59-01" src="/uploads/allimg/c181009/153Z2910S0B0-160I.png" />

引用范例对应干系:

 passes them to the Java method that the   <a href=劳务调派打点系统 programmer wishes to invoke.” CalltypeMethodA(jobject obj" class="aligncenter size-full wp-image-30096" title="Snipaste_2018-10-08_08-00-15" src="/uploads/allimg/c181009/153Z2910S4W0-210R.png" />

通过表格发明,除了上面界说的 StringClass、Throwable,其他的类(除了数组)都是以 jobject 的形式呈现的!事实上 jstring、 jclass 也都是 object 的子类。所以这里照旧和 Java 层一样,一切皆 jobject。(虽然,假如 jni 在 C 语言中编译的话是没有担任的观念的,此时 jstring、jclass 等其实就是 jobject!用了 typedef 转换罢了!!)

接下来是 JNIEnv * 这个指针,昆山软件开发,它提供了 JNI 中的一系列操纵的接口函数。

JNI 中操纵 jobject