下面我将为您详细讲解“Java JNI调用C函数实例分享(Java调用C函数)”的攻略。
什么是JNI?
JNI全称为Java Native Interface,即Java本地接口。它是一个开发者提供的桥梁,用于将Java虚拟机(JVM)连接到应用程序中的非Java代码(如C语言、C++等)。使用JNI可以使Java程序调用C语言等非java语言编写的代码或者API,同时也可以使非Java编写的子程序调用Java代码,从而实现Java代码与原生代码的交互。
JNI如何工作?
- Java部分:定义与C函数相对应的Java函数。
- JNI部分:将Java函数和C函数联系起来。
JNI的工作流程如下:
+---------------------+
| Java |
+---------------------+
↓ JNI调用
+---------------------+
| Java Native |
| Interface(JNI) |
+---------------------+
↓ C函数
+---------------------+
| C |
+---------------------+
如上所述,JNI将Java和C合并在一起,以便它们能够相互调用。
JNI开发环境的搭建
JNI开发涉及到Java、C(或C++)两种语言,需要在开发环境中安装Java环境和C/C++编程环境。并且需要安装与操作系统匹配的JNI头文件。
下面以windows系统和64位JDK为例,做一下环境搭建的步骤。
- 1.安装JDK
可以到Oracle官网下载安装包进行安装。
- 2.配置环境变量
在系统环境变量中添加JAVA_HOME,即Java安装的根目录,将Java的bin目录添加到系统PATH环境变量中。
- 3.编写Java代码和C代码
Java代码:
public class JNIDemo {
// 加载动态库
static {
System.loadLibrary("demo");
}
// 声明C函数
public native void helloWorld();
public static void main(String[] args) {
// 调用C函数
new JNIDemo().helloWorld();
}
}
C代码:
#include <jni.h>
#include "JNIDemo.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_JNIDemo_helloWorld(JNIEnv * env, jobject obj) {
printf("Hello World!\n");
}
- 4.生成JNI头文件
编译C代码时,使用 javac 工具生成相应的 JNI 头文件。
> javac JNIDemo.java
> javah –jni JNIDemo
- 5.编写C代码
在上一步中生成的JNIDemo.h文件中编写C代码,实现Java类声明的native函数。
- 6.生成动态库
使用GCC编译器将C代码编译成动态库。
> gcc -o demo.dll -shared -I"path\to\JDK\include" -I"path\toJDK\include\win32" JNIDemo.c
这里编译生成的是Windows上的dll库,如果您的开发环境是Linux或macOS,应该更改动态库的名称和命令。
- 7.运行程序
将编译后的动态库放到Java工程根目录下,并设置环境变量。
> set LD_LIBRARY_PATH=%LD_LIBRARY_PATH%;.
然后执行Java代码即可输出“Hello World!”。
示例
下面给出两个示例。
示例1:Java调用C语言的库函数sqrt()
Java代码:
public class SqrtDemo {
static {
System.loadLibrary("sqrt");
}
public native double sqrt(double num);
public static void main(String[] args) {
SqrtDemo demo = new SqrtDemo();
System.out.println(demo.sqrt(2.0));
}
}
C代码:
#include "jni.h"
#include <math.h>
JNIEXPORT jdouble JNICALL Java_SqrtDemo_sqrt(JNIEnv *env, jobject obj, jdouble num) {
return sqrt(num);
}
动态库生成:
> gcc -o sqrt.dll -shared -I"path\to\JDK\include" -I"path\toJDK\include\win32" sqrt.c -lm
示例2:Java调用C++的函数
Java代码:
public class CPPDemo {
static {
System.loadLibrary("cpp");
}
public native int add(int a, int b);
public static void main(String[] args) {
CPPDemo demo = new CPPDemo();
System.out.println(demo.add(1, 2));
}
}
C++代码:
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_CN_Hugo_JNIDemo_CPPDemo_add(JNIEnv *env, jobject thiz, jint a, jint b) {
return a + b;
}
#ifdef __cplusplus
}
#endif
动态库生成:
> g++ -o cpp.dll -shared -I"path\to\JDK\include" -I"path\toJDK\include\win32" CN_Hugo_JNIDemo_CPPDemo.cpp
总结
通过以上步骤可以轻松地编写出能够调用非Java语言编写的代码的Java程序,以此实现Java与原生代码的交互。当然,我们也需要在这个过程中留意一些问题,比如跨平台调用过程中传参的不同以及C/C++的内存管理。
希望这篇攻略能够帮到你,感谢阅读!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java jni调用c函数实例分享(java调用c函数) - Python技术站