初识JNI

JNI概念

JNI (Java Native Interface) 是 Java 平台的一个关键组件,它允许 Java 代码调用本地应用程序或库中的函数(通常是 C 或 C++ 代码),同时也允许本地代码调用 Java 方法。JNI 为 Java 和本地代码之间的交互提供了一个桥梁,使得开发者可以在 Java 应用程序中利用本地代码的强大功能,例如高性能计算、设备驱动程序访问等。

JNI 的用途

  • 性能优化:对于计算密集型任务,使用 C 或 C++ 编写的本地代码通常比纯 Java 代码更快。
  • 硬件访问:有些硬件设备只能通过本地代码访问,JNI 提供了一种途径来实现这种访问。
  • 跨语言集成:JNI 使得 Java 代码可以调用其他语言编写的库,反之亦然。

JNI 的工作流程

1.编写java测试类

2.利用java测试类生成C头文件

3.利用C头文件编写C代码

4.生成C库

5.java调用测试

第一步:编写java测试类

没有java基础,在ubuntu下用java相关命令简单写了个类,以下附有代码和执行命令。

代码如下:

package com.aijiao.test;
public class JNIDemo {
	//定义一个方法,该方法在C中实现
	public native String testHello();
	            
	public static void main(String[] args){
		//加载C文件
		System.loadLibrary("TestJNI2");
	    JNIDemo jniDemo = new JNIDemo();
		System.out.println(jniDemo.testHello());
	}
}

第二步:利用java测试类生成C头文件

生成命令如下:

javah -classpath . -jni com.aijiao.test.JNIDemo

该命令需要在java测试类的工程的bin目录下执行,这里没有新建工程,不存在bin目录,用javah执行总是出错,最后照着别人生成的头文件改了下,发现也可以用,头文件大致长这样:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_aijiao_test_JNIDemo */

//避免重复包含头文件

#ifndef _Included_com_aijiao_test_JNIDemo
#define _Included_com_aijiao_test_JNIDemo

//c++编译环境中才会定义__cplusplus (plus就是"+"的意思

#ifdef __cplusplus
extern "C" {  //告诉编译器下面的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)
#endif
/*
 * Class:     com_aijiao_test_JNIDemo
 * Method:    displayHelloJni
 * Signature: ()V
 */
JNIEXPORT jstring JNICALL Java_com_aijiao_test_JNIDemo_testHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

其实这个头文件不是必须的

第三步:利用C头文件编写C代码

有用javah生成头文件对应的c代码

#include "com_aijiao_test_JNIDemo.h"
#include <iostream>
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_com_aijiao_test_JNIDemo_testHello
(JNIEnv * env, jobject obj) {
	    //printf("this is C++ print");
	    return env->NewStringUTF("set value success");
}

没有用javah生成头文件对应的c代码

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

extern "C"
JNIEXPORT jstring JNICALL Java_com_aijiao_test_JNIDemo_testHello
(JNIEnv * env, jobject obj) {
	    //printf("this is C++ print");
	    return env->NewStringUTF("set value success");
}

两个略有差异,主要是要把extern “C”带上,不然会链接不到函数

第四步:生成C库

先拷贝两个头文件(jni.h和jni_md.h)过来再生成.so文件。jni.h和jni_md.h都在jdk目录下有,直接用find命令找需要拷贝到cpp文件夹下

g++ TestJNI.cpp -fPIC -shared -o libTestJNI2.so

第五步:java调用测试

整个测试工程文件层级如下:

以下java命令都是在java文件夹下执行的:

 根据.java文件生成.class文件:javac -d . JNIDemo.java

执行class文件:java com.aijiao.test.JNIDemo

指定libTestJNI2.so文件的路径,把.so路径加入环境变量:export LD_LIBRARY_PATH=/home/lxj/myproject/testJNI2/cpp:$LD_LIBRARY_PATH,不然会加载不上库会报错

 参考菜鸟教程:JNI 入门教程 | 菜鸟教程 (runoob.com),也有自己踩得坑,欢迎大家评论,有交流才会有进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值