jni开发–环境配置及解决方案

[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 包名.类名 即可

流程

  1. 先java 使用native在类中声明方法,
  2. 然后通过javah 生成.h文件
  3. 在c中引入.h文件并实现其方法
  4. 将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


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注