JNI字段描述符
- 用"["表示数组,比如"int []"表示为"[I"
- 对于类,要用全称"L包.子包.类名;"(前面有"L",后面有";"),比如"Ljava/lang/String;"
- 除String类外,其他的类都用Object表示,即"Ljava/lang/Object;"
native.c
/*
编译:gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <jni.h> //usr/lib/jvm/java-1.7.0-openjdk-amd64/include/jni.h
#if 0
typedef struct {
char *name; /* java里调用的函数名 */
char *signature; /* JNI字段描述符,用来表示Jave里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
}JNINativeMethod;
#endif
/*
注意:C函数比Java里的声明多2个参数: (JNIEnv *env, jclass cls)
*/
void c_hello(JNIEnv *env, jobject cls)
{
printf("hello world!\n");
}
/*
形参:int
返回值:int
*/
jint c_myprintf(JNIEnv *env, jobject cls, jint m)
{
printf("hello world! %d\n",m);
return 100;
}
/*
形参:String
返回值:String
*/
jstring JNICALL c_display_string(JNIEnv *env, jobject cls, jstring str)
{
//printf("this is c : %s\n",str);
//return "return from C";
const jbyte *cstr;
cstr = (*env)->GetStringUTFChars(env, str, NULL);
if (cstr == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}
printf("get string from java:%s\n", cstr);
(*env)->ReleaseStringUTFChars(env, str, cstr);
return (*env)->NewStringUTF(env, "return from c");
}
/*
形参:传入数组
返回值:int
*/
jint JNICALL c_display_data(JNIEnv *env, jobject cls, jintArray arr)
{
jint *carr;
jint i, sum = 0;
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return 0; /* exception occurred */
}
for (i = 0; i < (*env)->GetArrayLength(env,arr); i++) {
sum += carr[i];
}
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return sum;
}
/*
* Class: JNIDemo
* Method: display_array
* Signature: ([I)[I
*
* 形参:传入数组
* 返回值:输出数组
*/
jintArray JNICALL c_display_array(JNIEnv *env, jobject cls, jintArray arr)
{
jint *carr;
jint *oarr;
jintArray rarr;
jint i, n = 0;
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return 0; /* exception occurred */
}
n = (*env)->GetArrayLength(env,arr);
oarr = malloc(sizeof(jint)*n);
if(oarr == NULL) {
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return 0;
}
for(i = 0; i < n; i++) {
oarr[i] = carr[n-1-i];
}
/*Creates an jint array with thegiven length.*/
rarr = (*env)->NewIntArray(env,n);
if(rarr == NULL) {
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return 0;
}
/*Copies the contents of primitive arrays to or from a preallocated C buffer.
void (JNICALL *SetIntArrayRegion)
(JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf);
*/
(*env)->SetIntArrayRegion(env,rarr,0,n,oarr);
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
free(oarr);
return rarr;
}
/*
定义一个映射数组JNINativeMethod[]
可以注册多个本地函数
*/
static const JNINativeMethod methods[] = {
{"hello","()V",(void *)c_hello},
{"myprintf","(I)I",(void *)c_myprintf},
{"display_string","(Ljava/lang/String;)Ljava/lang/String;",(void *)c_display_string},
{"display_data","([I)I",(void *)c_display_data},
{"display_array","([I)[I",(void *)c_display_array},
};
/* 只要java 加载库System.loadLibrary 就会执行该函数 */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
/* 获得运行环境 */
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "JNIDemo");
if (cls == NULL) {
return JNI_ERR;
}
/* 建立联系 java<--->c*/
if((*env)->RegisterNatives(env,cls,methods,5) < 0)
return JNI_ERR;
return JNI_VERSION_1_4;
}
JNIDemo.java
/*
编译: javac JNIDemo.java
export LD_LIBRARY_PATH=.
java JNIDemo
自动生成字段描述符:
javac JNIDemo.java
javah -jni JNIDemo
*/
public class JNIDemo {
/* 静态代码块,加载库只执行一次 */
static {
/* 1. load 加载libnative.so */
System.loadLibrary("native");/* libnative.so */
}
//public native static void hello();//声明
public native void hello();//声明
public native int myprintf(int m);
public native String display_string(String str);
public native int display_data(int a[]);
public native int[] display_array(int a[]);
public static void main(String args[]){
JNIDemo d = new JNIDemo();
int a[] = {1, 2, 3, 4, 5};
int b[] = null;
int i;
/* 2. java <--> c 建立映射关系 */
/* 3.调用 */
d.hello();
System.out.println(d.myprintf(123));
System.out.println(d.display_string("this is java jni demo"));
System.out.println(d.display_data(a));
b = d.display_array(a);
for(i = 0; i < b.length; i++)
System.out.println(b[i]);
}
}
调试结果:
参考学习韦东山java视频整理
2017-07-25