JNI学习总结

对JNI的概念一直不是很清楚,这几天断断续续花了点时间在这上面,在此做个总结,备忘。

JNI中很重要的一个概念是它的接口指针,该接口指针管理着对jvm内部函数的调用。JNI接口指针是一个指向指针数组的指针,指针数组中的元素指向了接口函数,通过这些接口函数可以实现java和c/c++或者说本地代码的交互。

写一个helloworld记录和分析大概的过程:


package com.demo;

public class HelloWorld {

        private static int age;

        private String name;

        private static native void sayHello(String name);

        private native String getName();

        public static void main(String[] args){

                HelloWorld hw = new HelloWorld();

                hw.name = hw.getName();

                sayHello(hw.name);

                System.out.println(",Your age is: " + age);

                System.out.println("Done!");
        }

        static {

                System.loadLibrary("helloworld");
        }
}

在当前目录下编译:

javac -d . HelloWorld.java 


执行javah生成头文件:

javah -jni com.demo.HelloWorld

cp com_demo_HelloWorld.h com_demo_HelloWorld.c

编辑com_demo_HelloWorld.c,用不同的方式修改和访问java类中定义的各个属性和方法

#include "com_demo_HelloWorld.h"
#include <stdio.h>
#include <stdlib.h>
/*
 * Class:     com_demo_HelloWorld
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_demo_HelloWorld_sayHello
  (JNIEnv *env, jclass cls, jstring name){

	const jbyte *str;

	str = (*env)->GetStringUTFChars(env, name, NULL);

	if(str == NULL) return;

	printf("Hello %s", str);

	fflush(stdout);    //让缓存中的数据及时显示到屏幕上
}	
/*
 * Class:     com_demo_HelloWorld
 * Method:    getName
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_demo_HelloWorld_getName
  (JNIEnv *env, jobject thiz){
	
	char name[20];

	jclass cls = (*env)->GetObjectClass(env, thiz);

	jfieldID fid = (*env)->GetStaticFieldID(env, cls, "age", "I");

	if(fid == NULL) return NULL;

	(*env)->SetStaticIntField(env, cls, fid, 24);

	printf("Enter your name:\n");

	scanf("%s", name);

	return (*env)->NewStringUTF(env, name);
}

生成so库的命令为:

gcc -I /usr/lib/jvm/java-6-openjdk/include/linux/ -I /usr/lib/jvm/java-6-openjdk/include/ -shared -o libhelloworld.so -fpic com_demo_HelloWorld.c

在当前目录有了libhelloworld.so文件,

在这个过程中,发现c文件中的prinf语句会滞后于System.out.println调用,先打印出了", Your age is: 24",而不是"Hello XXX",后来想起来i/o缓存的机制,添加了fflush(stdout),让printf函数及时把内容显示到终端上,程序运行的结果终于正确了。

JNI中还有其他很多内容,运用好JINEnv *env这个接口指针是关键!(等学深点再补充相应的内容)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值