Java环境下的JNI调用

此文章写于2015.02.03,发布于网易博客,于2020.03.25迁移至此。

前言:记录学习过程便于记忆。经过多次尝试发现Java环境下的JNI调用与Andriod环境下的JNI调用有所不同,不知道是否正确。先记录一下Java环境下的JNI调用。

参考文章:http://www.cnblogs.com/youxilua/archive/2011/09/16/2178554.html
开始使用JNI:

先写一个Java文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.example.myjni; public class MyJni { //使用JNI的关键字native,决定我们那些方法能在我们的C文件中使用,只须声明,不必实现
public native void display(); public native double sum(double x,double y); // 用来读取我们写好的C语言编译好的dll,后缀是系统自己辨认 static { System.loadLibrary("myjni"); } public static void main(String[] args) { new MyJni().display(); System.out.println(new MyJni().sum(2.0, 3.0)); } }

把写好的类转换成.class文件

javac com\example\myjni\MyJni.java

把.class文件转换成头文件,成功的话就会在src目录下看到.h文件了

 javah com.example.myjni.MyJni

打开.h文件可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_myjni_MyJni */ #ifndef _Included_com_example_myjni_MyJni #define _Included_com_example_myjni_MyJni #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_myjni_MyJni * Method: display * Signature: ()V */ JNIEXPORT void JNICALL Java_com_example_myjni_MyJni_display (JNIEnv *, jobject); /* * Class: com_example_myjni_MyJni * Method: sum * Signature: (DD)D */ JNIEXPORT jdouble JNICALL Java_com_example_myjni_MyJni_sum (JNIEnv *, jobject, jdouble, jdouble); #ifdef __cplusplus } #endif #endif

native方法名称组成详解:

Java_为前缀 + 类的全名标识(包名+类名) + “_” + 方法名

写与.h文件对应的.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <jni.h> #include <stdio.h> #include "com_example_myjni_MyJni.h" JNIEXPORT void JNICALL Java_com_example_myjni_MyJni_display (JNIEnv *env, jobject obj) { printf("Hello MyJni!"); return; } JNIEXPORT jdouble JNICALL Java_com_example_myjni_MyJni_sum (JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a + b; }

windows下编译成dll文件,linux下编译成so文件.这里只讲dll的,.so的以后尝试了再说

首先查看我们的jdk文件夹,查看其include文件夹下是否存在Jni.h头文件。在的话,继续,否则重新安装jdk。

使用mingw编译.c文件(确保前面已经安装了mingw)

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"C:\Program Files\Java\jdk1.6.0_45\include" -I"C:\Program Files\Java\jdk1.6.0_45\include\win32" -shared myjni.c -o myjni.dll

命令 简单介绍
-Wall -D_JNI_IMPLEMENTATION_ 把我们的C文件编译成dll
-Wl,--kill-at   因为mingw默认是用@来进行分隔,会导致JNI机制不能读取,所以要删掉.. 
mingw官网解释
-I"C:\Program Files\Java\jdk1.6.0_45\include" -I"C:\Program Files\Java\jdk1.6.0_45\include\win32"  导入我们用的的jni需要的头文件…盘符,文件夹自己修改
-shared -o 输出配置,第一个参数为我们输出的名字(随便起),第二个参数为我们的C文件(随便起)

没出什么提示的话就是成功的了…

运行我们的JNI(用eclipse的话,我们把编译好的dll放到项目根目录,注意不是代码根目录)

 

输出结果

image

貌似java本身的输出,优先级比较高?

发布了4 篇原创文章 · 获赞 0 · 访问量 103

猜你喜欢

转载自blog.csdn.net/lxkscm/article/details/105092437