[Java的 – Ç] 在Java中的C函数调用 – 调用Java的C函数
你有没有想写一个Java程序库,但不会像某些语言 (如C) 执行? 这是一个原因,你阅读这篇文章, 或者你想使用从C函数,你可以跑得更快的Java程序的一些其他原因做!
要做到这一点, 你需要使用JNI库 (Java本地接口), 它可以从Java,反之亦然调用C函数. 基本上, 我们将用C编写的功能, 翻译成和Java库调用函数通过JNI该库. 我们将转向通过例如,它逐渐学会调用阶乘函数. 注意:我写了下面的文件相同的文件夹的所有桌面.
在执行过程中, 他在Ubuntu上工作, Linux发行版在Windows或其他可能略有不同. 我写这篇文章后协商 2 帖子 从Java调用C函数 和 从Java调用C函数, 然而,在实施过程中遇到了一些错误,我也贴的解决方案总是.
目录
步 1: 创建并转化为类文件的Java文件
步 2: 通过创建一个JAVAH头文件
步 3: 编译C库共享
步 4: 运行Java程序
修正了一些错误
步 1: 创建并转化为类文件的Java文件
在这个阶段,我们需要加载一个图书馆和函数声明是从C写的.
class CallCFunction { // report funcion write in C. private native long factorial(int n); public static void main(String[] args) { CallCFunction ccf = new CallCFunction(); int n = 5; System.out.println(n + "! = " + ccf.factorial(5)); } // load library factorial to use. static { System.loadLibrary("factorial"); } }
创建文件后,然后将其与命令翻译:
javac CallCFunction.java
步 2: 通过创建一个JAVAH头文件
C程序写在声明的Java文件的功能因子, 因此,我们需要创建头文件可用于.
javah -jni CallCFunction
上执行命令后, 文件 CallCFunction.h 将创建. 你注意线路 15,16, 这是我们将在C程序编写函数.
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class CallCFunction */ #ifndef _Included_CallCFunction #define _Included_CallCFunction #ifdef __cplusplus extern "C" { #endif /* * Class: CallCFunction * Method: factorial * Signature: (I)J */ JNIEXPORT jlong JNICALL Java_CallCFunction_factorial (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif
步 3: 编译C库共享
创建文件 factorial.c 含有阶乘函数. 复制 2 当前 15, 16 CallCFunction.h文件,并添加我们下面的变量程序.
#include <jni.h> #include <stdio.h> #include "CallCFunction.h" JNIEXPORT jlong JNICALL Java_CallCFunction_factorial (JNIEnv *env, jobject obj, jint n) { printf("funcion 'factorial' create in C programn"); int i; long result = 1; for (i = 2; i <= n; i++) { result *= i; } return result; }
在这, 排 4 是阶乘函数, jlong 仅将返回值作为长, 2 参数 JNIEnv的* ENV 和 jobject OBJ 是默认的,你不需要注意 (我也弄不明白这件事), 第一个参数 3 是 我们jint 是指变量 INTñ 分别在功能 阶乘(INTñ) 文件CallCFunction.java.
现在,我们将创建一个图书馆和它分享给包含文件夹的java (你的目录可以包含不同的java). 在文件我们装库CallCFunction.java 阶乘 命令 的System.loadLibrary(“阶乘”);, 因此,我们的图书馆拥有多个字符串 LIB 即前 libfactorial.so
gcc -shared -I/usr/lib/jvm/jdk1.8.0_05/include/ factorial.c -o libfactorial.so
步 4: 运行Java程序
现在我们单独运行程序享受成功.
java -Djava.library.path=. CallCFunction
蔡 -Djava.library.path =. 被告知该程序可以找到刚刚在当前目录下创建的库 (libfactorial.so文件夹). 也可以将环境变量设置为与命令的目录 出口LD_LIBRARY_PATH =. (在底部的点), 同时可以运行在命令权 java的CallCFunction
修正了一些错误
在执行过程中, 我遇到的一些误区, 如果你像我一样尝试以下解决方案, 如果有其他错误,你可以在这里分享到交换.
1. 无法转换java命令带
如果你不能用命令javac的java的jdk安装维修不过,也许你还没有为它设置环境变量. 你查一下java文件, javac的, JAVAH位于任意目录,然后继续设置环境变量的文件夹. 假设中的JDK “/usr / lib目录/ JVM / jdk1.8.0_05 /”
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_05/ export PATH=$JAVA_HOME/bin:$PATH
2. 没有找到该库jni.h
如果翻译错误,这个图书馆没有找到,那么也许它没有设置环境变量使用. 你需要这样做. 他的例子:
export LD_LIBRARY_PATH=/usr/lib/jvm/jdk1.8.0_05/include/
3. 错误创建头文件
在创建一个头文件的过程 (CallCFunction.h), 您可能会遇到下面的错误:
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: HelloWorld at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:129) at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107) at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64) at com.sun.tools.javah.JavahTask.run(JavahTask.java:503) at com.sun.tools.javah.JavahTask.run(JavahTask.java:329) at com.sun.tools.javah.Main.main(Main.java:46)
当您在不包含创建时的翻译文件* *的.java .class文件的目录中执行命令的. 换句话说,无法找到的* .class. 您需要设置 类路径 以包含类文件的文件夹. 假设它位于 桌面.
javah -jni -classpath /home/nguyenvanquan7826/Desktop/ HelloWorld
4. 没有找到该库jni_md.h
你找出这个库计算机. 猫, 它位于 /usr / lib目录/ JVM / jdk1.8.0_05 /在include / linux, 现在只是把它复制到 /usr / lib目录/ JVM / jdk1.8.0_05 /有/ (forder文件包含jni.h).
我得到的错误-classpath ,,如何找到在Android项目有效类路径 ,,需要帮助
我的包名 :包com.example.sunil.application;
你好, 也许你有在我的岗位了一些错误. 请参阅和点击此处查看: https://www.cachhoc.net/2014/07/10/java-c-goi-ham-c-trong-java-call-c-function-in-java-2/#fixerror