JAVA学习笔记—JNI实现

参考资料-韦东山老师第四期资料
主要参考视频讲解和相关文档,进行java的一个小的学习总结。本文讲解JNI的实现原理和代码实验。
整体流程如下:
在这里插入图片描述
下面用代码来实现下,由于我这边使用的windows的电脑,所以采用虚拟机的方式,安装ubuntu(需要安装java,参考网上其他教程即可)进行操作。
先实现一个java程序和一个c程序(命名随意)

JniDemo.java

public class JniDemo{
	//静态代码块,在构造一个对象之前就会执行,并且只执行一次		
	static{
		/*加载c库*/
		System.loadLibrary("native");//libnative.so,到时有native.c生成
	}
	public native static void hello(); 	//native 表示所声明的函数是本地语言实现的即C语言
	public static void main(String args[]){
		
		/*调用函数*/
		hello();
	}
}

native.c,在这里实现java和c库的映射关系,c_hello与java中的hello

#include<stdio.h>
#include<jni.h>

#if 0//从思维导图中摘录下来
typedef struct {
    char *name;          /* Java里调用的函数名 */
    char *signature;    /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
    void *fnPtr;          /* C语言实现的本地函数 */
} JNINativeMethod;
#endif
void c_hello()
{
	
	printf("hello world \n");
}
static const JNINativeMethod methods[] = {
	{"hello", "()V", (void *)c_hello},  //"()V "是怎么的来的?
}; 
 
//system.loadLibrary
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)//参考jni.pdf 117页,有示例用法
{
	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");   //查找类JniDemo.java中的类名
	if (cls == NULL) {
		return JNI_ERR;
	}
	///*建立java和c的映射*/
	if(((*env)->RegisterNatives(env,cls,methods,1))<0)   //看思维导图,需要使用RegisterNatives方法,RegisterNatives方法是前面获得运行环境的方法,用法看jni.pdf 101页,methods数组进行java和c的函数的映射
		return JNI_ERR;
	
	return JNI_VERSION_1_4;
}

下面来编译下看:

//进入到相应目录下
javac JniDemo.java
gcc -shared -o libnative.so native.c //编译为动态链接库
//提示错误: fatal error: jni.h: No such file or directory
//找下看find -name jni.h
//./book/jdk1.6.0_45/include/jni.h,这个可能每个人不太一样

编译时包含下这个头文件需要-I加上
gcc -I/home/book/jdk1.6.0_45/include/jni.h -shared -o libnative.so native.c

/home/book/jdk1.6.0_45/include/jni.h:27:20: fatal error: jni_md.h: No such file or directory
继续搜索看下jni_md.h在哪个位置,包含这个头文件即可(/home/book/jdk1.6.0_45/include/linux)

最终的编译命令如下:
gcc -I/home/book/jdk1.6.0_45/include/ -I/home/book/jdk1.6.0_45/include/linux/ -fPIC -shared -o libnative.so native.c
( -fPIC 是编译时提示要加上)

ls查看下
JniDemo.class  JniDemo.java  libnative.so  native.c
libnative.so 库已经生成

//然后执行下
java JniDemo
//会提示找不到库(Exception in thread "main" java.lang.UnsatisfiedLinkError: no native in java.library.path
),需要导出环境变量,库在当前路径下,之后执行就可以出现结果,java成功调用到了c语言中的c_hello()
export LD_LIBRARY_PATH =.

java JniDemo
hello world//成功执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值