继续上一篇博文eclipse搭建JNI开发环境,现在我们从代码角度分析,C和Java混合编程时能实现的功能。
使用javah命令,编译生成.h头文件时,每个函数,至少都会有两个参数。JNIEnv 和jclass/jobject。其中,当native方法是静态方法(类方法)时,第二个参数是jclass,当native方法是成员方法时,第二个参数是jobject。其余的参数,会根据你在java文件中声明的方法参数类型,生成具体的签名。jni中类型在jni头文件中定义规则如下:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
对应签名:
java类型 | jni类型 | 类型签名 |
char | jchar | C |
int | jint | I |
long | jlong | J |
float | jfloat | F |
double | jdouble | D |
boolean | jboolean | Z |
byte | jbyte | B |
short | jshort | S |
void | V | |
类 | L全限定名;,比如String, 其签名为Ljava/lang/util/String; | |
数组 | [类型签名, 比如 [B |
Jni.java 文件中,对应7个native方法。
1.调用C语言的printf函数,输出固定内容。
public static native void print();
2.转入指定字符串,用printf函数输出。
public static native void print(String str);
3.用C语言实现拼接字符串的功能,并返回给java。
public static native String append(String str);
4.传入字符串,作为Test类构造函数的函数,C语言调用Java类的构造函数,生成jobject,操纵Test类的所有方法和属性。
public native void test(String test);
5.传入Test类的对象,操纵操纵Test类的所有方法和属性。
public native void test(Test test);
6.将传入的字节数组转16进制字符串返回。
public native String toHex(byte[] test);
7.将传入的字符串转成16进制字节数组返回。
public native byte[] toBytes(String test);
完整示例代码如下:
com_flueky_jni_Jni.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_flueky_jni_Jni */
#ifndef _Included_com_flueky_jni_Jni
#define _Included_com_flueky_jni_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_flueky_jni_Jni
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_flueky_jni_Jni_print__
(JNIEnv *, jclass);
/*
* Class: com_flueky_jni_Jni
* Method: print
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_flueky_jni_Jni_print__Ljava_la