步骤
/**
* 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相同的目录。
分享到:
相关推荐
在这个"Java JNI HelloWorld"示例中,我们将深入探讨如何使用JNI来创建一个简单的“Hello, World!”程序。 首先,`HelloWorld.java`是Java源代码文件,其中定义了一个本地方法`native void sayHello()`。在Java中,...
这一步会根据`HelloWorld.java`中的`native`方法自动生成对应的JNI头文件。 ##### 4. 处理JNI头文件 将生成的`com_helloworld_HelloWorld.h`文件移动到`HelloWorld.java`所在的目录: ```bash mv ...
在"jni-helloWorld"这个项目中,我们看到的是一个JNI的入门示例,主要目的是帮助开发者理解如何使用JNI来调用本地(非Java)代码。 首先,"HelloWorld"是编程中的经典例子,通常用于展示一种新语言或技术的基本用法...
本示例“JNI-HelloWorld”就是关于如何使用JNI将Java与C语言结合,实现一个简单的“Hello, World!”程序。 首先,我们需要理解JNI的基本概念。JNI定义了一套接口和数据类型,使得Java代码能够声明本地方法(即非...
在这个"android jni helloworld"的例子中,我们将深入理解如何使用JNI在Android应用中实现一个简单的“Hello, World!”程序。 1. **JNI基础知识**: - JNI是一种接口,允许Java代码和其他语言写的代码进行交互。 ...
本压缩包"编译好的Android JNI HelloWorld"提供了一个基础示例,帮助开发者验证其Android NDK开发环境是否已正确搭建。 JNI在Android开发中的作用主要体现在以下几个方面: 1. 性能优化:对于计算密集型任务,如...
通过这个简单的JNI HelloWorld示例,你可以了解到Java与本地代码交互的基本步骤。实际开发中,JNI可以用来实现性能敏感的部分,访问操作系统API,或者整合其他已有的C/C++库。理解并熟练掌握JNI,对Java开发者来说是...
本示例将详细介绍如何在Android Studio(Stuido)中创建并使用一个简单的JNI(HelloWorld)例子,包括生成本地方法库(so文件)以及在其他项目中调用。 1. **创建JNI项目** 首先,我们需要创建一个新的Android ...
生成HelloWorld.h文件(若提示找不到HelloWorld类文件,Java代码中不要写package) 有package时,在包所在目录下打开终端,输入命令javah -jni com.gjl.jnitest.HelloWorld (com.gjl.jnitest为包名) 生成 ...
return(*env)->NewStringUTF(env, "Hello World from JNI !"); } JNIEXPORT jdouble JNICALL Java_com_xxx_hello_HelloJni_add(JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a + b; } JNIEXPORT ...
本教程将围绕"JNI之HelloWorld"展开,带你了解JNI的基本使用。 首先,我们需要理解JNI的核心概念。JNI为Java程序员提供了一个接口,通过这个接口,Java代码可以调用C/C++编写的本地方法,同时C/C++代码也可以调用...
在"JNI HelloWorld"这个主题中,我们主要讨论的是如何通过JNI技术在Java程序中调用C语言编写的函数,实现Java与本地代码的无缝集成。 1. **JNI简介** JNI是一种接口,为Java虚拟机(JVM)提供了与本地代码(如C/...
JNIEXPORT void JNICALL Java_HelloWorld_sayHello(JNIEnv *env, jobject obj) { printf("Hello from C++!\n"); } ``` 这里,`JNIEXPORT`和` JNICALL`是JNI约定的宏,用于正确导出和导入函数。`JNIEnv*`是一个指向...
javah -jni HelloWorld ``` 这会生成一个`HelloWorld.h`文件,包含了JNI函数原型。 3. **编写本地代码**:根据生成的头文件,编写C/C++实现。例如: ```c++ #include "HelloWorld.h" JNIEXPORT void JNICALL...
javah -jni HelloWorld ``` 这将生成一个`HelloWorld.h`头文件,其中包含了Java native方法的C/C++原型。 3. **编写本地库代码**: 根据生成的头文件,我们编写C/C++源代码,实现Java中声明的native方法。例如...
"jni之ndk hello world"是一个典型的入门教程,旨在帮助开发者理解如何在Android应用中使用JNI和NDK编写原生代码。 首先,让我们详细解释JNI。JNI是Java平台的一个接口,它定义了一组API,让Java代码能够调用本地...
在上述的"Java JNI 简单教程"中,通过一个简单的HelloWorld示例介绍了如何使用JNI。首先,你需要创建一个Java类,例如`HelloWorld`,在这个类中声明一个native方法,如`displayHelloWorld()`。这个native关键字告诉...
这篇“JNI入门教程之HelloWorld篇”文档将引导我们了解如何使用JNI来开发一个简单的应用程序。 首先,我们需要明白JNI的核心概念:本地方法接口。它提供了一种方式,让Java虚拟机(JVM)能够调用非Java语言编写的...
### JNI入门教程详解:HelloWorld篇 #### 一、引言与背景 Java Native Interface (JNI) 是Java语言与本地代码交互的桥梁,允许Java应用调用C或C++等本地语言编写的代码,这对于扩展Java功能、提高性能或集成已有非...
在C/C++中,你会实现`displayHelloWorld`方法,使用头文件中定义的`JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject);`函数签名。 **调用中考虑的问题** 1. **类型映射**:Java和C/...