Mac系统下JNI实现native方法(Java调用C语言的实现)-Demo
转载自原文:https://blog.csdn.net/u010853261/article/details/53470514?
JNI实现native方法(Java调用C语言的实现)
JNI的实现步骤如下:
1. 编写带有native声明的方法的Java类
2. 使用javac命令编译编写的Java类
3. 使用java -jni **来生成后缀名为.h的头文件
4. 使用其他语言(C、C++)实现本地方法
5. 将本地方法编写的文件生成动态链接库
下面给出一个最简单的
1. 编写含有native方法的类:
public class HelloWorld{ public native void hello(); static { //设置查找路径为当前项目路径 System.setProperty("java.library.path", "."); //加载动态库的名称 System.loadLibrary("hello"); } public static void main(String[] args){ new HelloWorld().hello(); } }
2.编译代码:
$javac HelloWorld.java
这时就会生成HelloWorld.class文件
3. 使用java -jni **来生成后缀名为.h的头文件
根据上面的Java代码,调用jni命令
$javah -jni HelloWorld
这就会生成HelloWorld.h文件,这个文件里面的内容是不能被修改的。下面我们看一下这个文件内容:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: hello * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_hello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
4. 使用其他语言(C、C++)实现本地方法
这里创建HelloWorldImpl.c源文件实现功能:
#include "jni.h" #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env,jobject obj){ printf("Hello World!\n"); return; }
5. 将本地方法编写的文件生成动态链接库
使用命令生成动态链接库:
$gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.7.0_72.jdk/Contents/Home/include/ HelloWorldImpl.c -o libhello.jnilib
后面的那个libhello.jnilib就是生成的动态链接库;但是运行这个命令时报错了,显示:
In file included from HelloWorldImpl.c:1: /Library/Java/JavaVirtualMachines/jdk1.7.0_72.jdk/Contents/Home/include/jni.h:45:10: fatal error: 'jni_md.h' file not found #include "jni_md.h" ^ 1 error generated.
提示jni_md.h这个文件找不到;我们执行下面的命令拷贝一份:
¥sudo cp /Library/Java/JavaVirtualMachines/jdk1.7.0_72.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.7.0_72.jdk/Contents/Home/include
后面在执行生成动态链接库的命令就成功了,下面图示最后的文件列表:
5.最后执行可执行文件
$ java HelloWorld
得到运行结果。
6. 注意:
我们使用gcc生成的动态链接库;在Mac下的后缀是固定的,就是.jnilib。此外我们生成的动态链接库必须是以lib开头的,而且我们加载动态库时需要去掉前面的lib.比如上面的例子,生成的是libhello.jnilib,后面调用加载动态库时使用的是hello这个动态库名。