一、JNI 小练习

学习 JNI 参考了以下地址写了一个例子

http://www.cnblogs.com/android-html5/archive/2011/10/28/2534101.html

1.写java文件
2.编译java生成class
3.生成C/C++头文件。
4.写C/C++文件
5.编译生成dll(Window下)或so文件
6.运行java程序


1、写Java

public class Hello {

static {
System.load("/root/jni/libhello.so");
}


public void callback(String str) {
System.out
.println("I was invoked by native method, but I 'm a java method"
+ str);
}


public native void docallback();


public static void main(String[] args) {
new Hello().docallback();
}

}


2、编辑Java

javac Hello.java

生产了 Hello.class 类文件


3、生产JNI 文件

javah Hello

系统多了一个Hello.h 头文件

里面包括了一个Java类的方法声明


4、 编写 Hello.c 实现JNI 接口


#include "jni.h"
#include "jni_md.h"
#include "Hello.h"
JNIEXPORT void JNICALL Java_Hello_docallback
  (JNIEnv * env, jobject obj){
jclass cls = (*env)-> GetObjectClass(env,obj);
jmethodID callbackID = (*env)->GetMethodID(env,cls , "callback" , "(Ljava/lang/String;)V") ;
 if(callbackID == NULL)
 {
printf("getMethodId is failed \n");
}


jstring native_desc = (*env)->NewStringUTF(env," I am Native");
(*env)->CallVoidMethod(env,obj , callbackID , native_desc);


}


5、编辑Hello.c 文件为二进制文件

其中命令中的 -I 是 告诉gcc 编译器  引用的JNI 头文件地址 在Java路径中。 不同用户不同地址哦

gcc -fPIC -D_REENTRANT -I /usr/java/jdk1.7.0_45/include -I /usr/java/jdk1.7.0_45/include/linux -c Hello.c

生产了一个 Hello.o 二进制文件

6、生产动态连接库


gcc -shared Hello.o -o libhello.so


7、测试 Hello 类   
java -Djava.library.path=.  Hello

8、比对结果

正确打印了需要的信息

I was invoked by native method, but I 'm a java method I am Native


注意:


1、C和C++ 差别:

C++

  env->NewStringUTF(" I am Native");

C:

 (*env)->NewStringUTF(env," I am Native");


2、编译差别

如果hello.c 名字是cpp 说明是c++程序


请用 g++ 编译


gcc -fPIC -D_REENTRANT -I /usr/lib/jvm/java/jdk1.8.0_73/include -I /usr/lib/jvm/java/jdk1.8.0_73/include/linux -cHello.cpp   -lstdc++  -o Hello2


gcc -shared Hello2 -o libhello.so



java -Djava.library.path=.  Hello


报错:

undefined symbol: __gxx_personality_v0

编译 C++ 的时候 添加参数   -lstdc++


3、官方文档地址


http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp23717


其他参考地址:


二、JNI学习积累之二 ---- 数据类型映射、域描述符说明
http://blog.csdn.net/qinjuning/article/details/7599796

三、 操作JNI函数以及复杂对象传递
http://blog.csdn.net/qinjuning/article/details/7607214

四、JNI学习(四)、本地方法创建java对象,以及对字符串的操作

http://blog.csdn.net/lonelyroamer/article/details/7958407

五、JNI学习(五)、引用、缓存、异常、多线程
http://blog.csdn.net/lonelyroamer/article/details/7962928

JNI学习积累之一 ---- 常用函数大全

http://blog.csdn.net/qinjuning/article/details/7595104


JNI底层原理  后半部分可以看到如果利用第三方的dll或者 so 库

http://blog.csdn.net/hackooo/article/details/48395765

http://blog.csdn.net/hackooo/article/details/48395765


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值