[toc]
为什么
由于要实现各种语言之间的调用,尤其是java调用脚本等本地程序.因此就要学习一下java如何调用其他语言的. 这个是java与c之间的交互. 还有ndk的. 反正没事做੧༼ ◕ ∧ ◕ ༽┌∩┐
jni
这里是使用的jdk1.8,网上的资料有1.6的不一样的地方就在于 生成java的头文件的方式;
1.6是在src文件夹中 先用javac 生成字节码class文件,然后通过javah -jni + 包名.类名.class 生成头文件.
1.7以后 都是不用javac 直接在src 中 javah -jni 包名.类名 即可
流程
- 先java 使用native在类中声明方法,
- 然后通过javah 生成.h文件
- 在c中引入.h文件并实现其方法
- 将c实现编译成链接库 .so 或.dll都行
具体操作步骤
搞了好久 因为是window下的使用的mingw,和gcc还是有点区别的,毕竟是linux和windows的区别,尤其是在路径上.
再来一个坑,就是mingw是32位的 你jdk是64位的话还要下mingw -w64 没办法呀;
java
package jniandndk;
// java代码很 简单的
public class MyJniU {
public static native void show();
public static void main(String[] args) {
show();
}
static {
//这个不行的话就用load
// System.loadLibrary("jniandndk_MyJniU");
System.load("E:\\java\\work\\Myleetcode\\src\\jniandndk_MyJniU.dll");
}
}
c代码
然后进行头文件生成
javah -jni jniandndk.MyJniU
// 这个就是 包名加类名, 但是这个命令的运行要在src的目录下进行,而且java命令可以用.
// 如果java命令不能用就配置一下path
会生成一个.h文件,代码如下我们不用去改
#include <jni.h>
/* Header for class jniandndk_MyJniU */
#ifndef _Included_jniandndk_MyJniU
#define _Included_jniandndk_MyJniU
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jniandndk_MyJniU
* Method: show
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jniandndk_MyJniU_show
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
然后就是实现这个头文件的 函数; 有一点这个头文件生成的函数中参数没有命名只有类型,我们在复制函数头的时候参数要加名称,例如上面.h 文件是JNIEnv *
我们c要添加名称变成JNIEnv * env
#include<jni.h>
#include<stdio.h>
#include"jniandndk_MyJniU.h"
// 看函数参数,我就在这里被坑了
JNIEXPORT void JNICALL Java_jniandndk_MyJniU_show(JNIEnv *env, jclass jcl){
printf("zheshic++");
return;
}
c编译
进行c文件的编译,windows 下的mingw 的编译成dll
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I "c:\Program Files\Java\jdk1.8.0_45\include" -I "c:\Program Files
\Java\jdk1.8.0_45\include\win32" -shared -o jniandndk_MyJniU.dll jniandndk_MyJniU.c
linux下的编译成so
ls -lrt /usr/bin/java
# /usr/bin/java -> /etc/alternatives/java
ls -lrt /etc/alternatives/java
# lrwxrwxrwx 1 root root 73 Jan 7 00:17 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-5.b12.el7_4.x86_64/jre/bin/java
# 使用如下命令 记住要带fPIC
gcc -I /usr/java/jdk1.8.0_151/include/ -I /usr/java/jdk1.8.0_151/include/linux/ -fPIC -shared -o jniandndk_MyJniU.so jniandndk_MyJniU.c
centos7自带openjdk 但是没有inclue文件夹, 所以还要重新装一下那个jdk8. 就到官网下一个linux rpm版 然后安装一下就行了 路径为/usr/java/jdk1.8.0_151
java运行
记住System.Load("绝对路径");
直接运行就可以了 ,
– linux下的
– windows下的 mingw-w64
发表回复