linux下JNI的demo

本文详细介绍了如何使用Java访问C/C++通过JNI技术实现交互,并以Ubuntu环境为例,通过六个步骤来实现一个简单的JNI程序。包括编写Java和C/C++代码,生成头文件,编译生成共享库,最后运行Java程序并调用C/C++方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java访问C/C++有6步
1.写java文件
2.编译java生成class
3.生成C/C++头文件。
4.写C/C++文件
5.编译生成dll(Window下)或so文件
6.运行java程序
下面介绍ubutun下一个JNI例子

1.编写Sample1.java文件:

  

 public class Sample1
  {
	public native int intMethod(int n);
	public native boolean booleanMethod(boolean bool);
	public native String stringMethod(String text);
	public native int intArrayMethod(int[] intArray);

	public static void main(String[] args)
	{
	System.loadLibrary("Sample1");
	Sample1 sample = new Sample1();
	int square = sample.intMethod(5);
	boolean bool = sample.booleanMethod(true);
	String text = sample.stringMethod("JAVA");
	int sum = sample.intArrayMethod(
	new int[]{1,1,2,3,5,8,13} );
	
	System.out.println("intMethod: " + square);
	System.out.println("booleanMethod: " + bool);
	System.out.println("stringMethod: " + text);
	System.out.println("intArrayMethod: " + sum);
 }
 }

 两个地方要注意,
 一。上面的方法都用到了native关键字。
 二。System.loadLibrary("Sample1");这句中"Sample1"是我们在第5步中得到的库的名字,在window下是"Sample1.dll",在unix下要加前缀"lib",即"libSample1.so"。
 
2.编译java文件:
javac  Sample1.java
    无错生成Sample1.class文件
3.生成C/C++头文件
javah  Sample1
    生成Sample1.h
使用命令 cat  Sample1.h 查看,内容为:

	 /* DO NOT EDIT THIS FILE - it is machine generated */
	#include <jni.h>
	/* Header for class Sample1 */
	
	#ifndef _Included_Sample1
	#define _Included_Sample1
	#ifdef __cplusplus
	extern "C" {
	#endif
	
	JNIEXPORT jint JNICALL Java_Sample1_intMethod
	(JNIEnv *, jobject, jint);
	
	JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
	(JNIEnv *, jobject, jboolean);
	
	JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
	(JNIEnv *, jobject, jstring);
	
	JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
	(JNIEnv *, jobject, jintArray);

	#ifdef __cplusplus
	}
	#endif
	#endif

 我们可以对比看看java文件中对应的方法


 4.编写C/C++代码

   Sample1.c:

 

#include "Sample1.h"
 #include <string.h>
 JNIEXPORT jint JNICALL Java_Sample1_intMethod
 (JNIEnv *env, jobject obj, jint num) {
 return num * num;
 }
 JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
 (JNIEnv *env, jobject obj, jboolean boolean) {
 return !boolean;
 }
 JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
 (JNIEnv *env, jobject obj, jstring string) {
 const char *str = (*env)->GetStringUTFChars(env, strin
 char cap[128];
 strcpy(cap, str);
 (*env)->ReleaseStringUTFChars(env, string, str);
 return (*env)->NewStringUTF(env, strupr(cap));
 }
 JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
 (JNIEnv *env, jobject obj, jintArray array) {
 int i, sum = 0;
 jsize len = (*env)->GetArrayLength(env, array);
 jint *body = (*env)->GetIntArrayElements(env, array, 0
 for (i=0; i<len; i++)
 { sum += body[i];
 }
 (*env)->ReleaseIntArrayElements(env, array, body, 0);
 return sum;
 }
 void  main(){}

Sample1.cpp:

#include "Sample1.h"
#include <string.h>
NIEXPORT jint JNICALL Java_Sample1_intMethod
 (JNIEnv *env, jobject obj, jint num) {
 return num * num;
}
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
 (JNIEnv *env, jobject obj, jboolean boolean) {
 return !boolean;
}
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
 (JNIEnv *env, jobject obj, jstring string) {
 const char *str = env->GetStringUTFChars(string, 0);
 char cap[128];
 strcpy(cap, str);
 env->ReleaseStringUTFChars(string, str);
 return env->NewStringUTF(strupr(cap));
}
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
 (JNIEnv *env, jobject obj, jintArray array) {
 int i, sum = 0;
 jsize len = env->GetArrayLength(array);
 jint *body = env->GetIntArrayElements(array, 0);
 for (i=0; i<len; i++)
 { sum += body[i];
 }
 env->ReleaseIntArrayElements(array, body, 0);
 return sum;
 }
 void main(){}

两个差别就是JNIEnv这个类
  C中使用 jsize len = (*env)->GetArrayLength(env,array);
  C++中使用 jsize len = env->GetArrayLength(env,array);  
 
5.生成共享库文件
 编译Sample1.c文件
 gcc -fPIC -D_REENTRANT -I/usr/lib/java/include -I/usr/lib/java/include/linux -c Sample1.c 
 编译用到了jdk include中jni.h,include/linux中jni_md.h两个头文件
 /usr/lib/java/include        是jin.h路径
 /usr/lib/java/include、linux 是jni_md.h路径
 此时生成Sampel.o文件
 运行:
 gcc -shared Sample1.o -o libSample1.so
 生成libSample1.so


6.运行java程序
libSample1.so文件拷贝到java的加载库LD_LIBRARY_PATH指向的路径中:
如果没有足够权限,可以这样:
(1).在/home下建立一个用来存放.so库文件的目录,比如/home/xxx/lib
(2).把libSample1.so文件拷贝到该目录下
(3).运行:export LD_LIBRARY_PATH=/home/xxx/lib  (只在当前shall下有效...)
现在运行java Sample1
一切正常后,可以看到运行結果输出:
intMethod: 25
booleanMethod: false
stringMethod: JAVA
intArrayMethod: 33
完成第一个JNI程序。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值