java JNI HelloWorld

本文详细介绍了如何使用Java和C语言结合实现JNI技术,包括创建类、编译程序、生成头文件、编写C语言实现本地方法、编译C代码生成动态库,以及运行程序并打印HelloWorld!。

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

步骤
/**
* 1。Create a class that declares the native method HelloWorld.java
* 2。Use javac to compile the program HelloWorld.class
* 3。Use javah to generate header file HelloWorld.h
* 4。Write the C implementation of the native method HelloWorld.c
* 5。Compile C code and generate native library HelloWorld.dll or HelloWorld.so
* 6。Run the program using the java interpreter “Hello World!”
* */

class HelloWorld {
//声明本地方法
private native void print();
public static void main(String[] args) {
new HelloWorld().print();
System.out.println(System.getProperty("java.library.path"));
//.:/Library/Java/Extensions: /System/Library/Java/Extensions:/usr/lib/java
}

//加载本地库文件
static {
// System.setProperty("java.library.path", "/Users/rye/workspace/JniTest/src");
// System.loadLibrary("HelloWorld");
System.load("/Users/rye/workspace/JniTest/src/HelloWorld.so");
}
}



javah -jni HelloWorld

HelloWorld.h:

#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif


HelloWorld.c:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
// /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers

// gcc -fPIC -D_REENTRANT -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -c HelloJNI.c
// 注:
/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers 是jni.h头文件所在的路径
/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers 是jni_md.h所在的路径
// gcc -shared HelloWorld.o -o HelloWorld.so
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj){
printf("Hello World!\n");
return;
}

-I:是为了include两个文件jni.h和jni_md.h,用JNI必须关联的头文件。
-fPIC:表示编译为位置独立的(可重定向的)代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-L.:表示要连接的库在当前目录中
-lHelloWorld:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

System.load 和 System.loadLibrary详解:

1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。

2.System.load 参数为库文件的绝对路径,可以是任意路径。
例如你可以这样载入一个windows平台下JNI库文件:
System.load("C:\\Documents and Settings\\TestJNI.dll");。

3. System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
例如你可以这样载入一个windows平台下JNI库文件
System. loadLibrary ("TestJNI");

这里,TestJNI.dll 必须是在java.library.path这一jvm变量所指向的路径中。
可以通过如下方法来获得该变量的值:
System.getProperty("java.library.path");
默认情况下,在Windows平台下,该值包含如下位置:
1)和jre相关的一些目录
2)程序当前目录
3)Windows目录
4)系统目录(system32)
5)系统环境变量path指定目录

4.如果你要载入的库文件静态链接到其它动态链接库,例如TestJNI.dll 静态链接到dependency.dll, 那么你必须注意:
1)如果你选择
System.load("C:\\Documents and Settings\\ TestJNI.dll");
那 么即使你把dependency.dll同样放在C:\\Documents and Settings\\下,load还是会因为找不到依赖的dll而失败。因为jvm在载入TestJNI.dll会先去载入TestJNI.dll所依赖 的库文件dependency.dll,而dependency.dll并不位于java.library.path所指定的目录下,所以jvm找不到 dependency.dll。
你有两个方法解决这个问题:一是把C:\\Documents and Settings\\加入到java.library.path的路径中,例如加入到系统的path中。二是先调用
System.load("C:\\Documents and Settings\\ dependency.dll"); 让jvm先载入dependency.dll,然后再调用System.load("C:\\Documents and Settings\\ TestJNI.dll");
2)如果你选择
System. loadLibrary ("TestJNI");
那么你只要把dependency.dll放在任何java.library.path包含的路径中即可,当然也包括和TestJNI.dll相同的目录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值