jni打怪第二篇--Java jni 开发

3 篇文章 0 订阅

JNI 是 Java本地接口 (Java Native Interface),是为了方便 Java 调用 C 、C++等本地代码而封装的一层接口。

学习下 Java 开发环境下 jni 的使用。

1.新建一个类

新建一个类,就用它来测试。

package com.lah.studyjni;

public class HelloJni {

    static {
        System.loadLibrary("HelloJni");//注释1
    }

    public native void setParam(String param);//注释2
    public native String getJniParam();//注释3

    public static void main(String[] args) {
        HelloJni helloJni = new HelloJni();
        helloJni.setParam("test");//注释4
        System.out.println("JniParam:" + helloJni.getJniParam());//注释5
    }
}

注释1 处加载 HelloJni 库。
注释2、注释3 处声明 native 方法。
注释4、注释5 处调用 native 方法。

2.编译生成class文件和h文件

2.1 生成class文件

在 IntelliJ IDEA 的 Terminal 栏执行 javac com/lah/studyjni/HelloJni.java 生成 HelloJni.class

留意下,javac 命令要跟着完整路径,我把生成的 class 文件和 java 文件放在同级目录。

2.2 生成h文件

在 IntelliJ IDEA 的 Terminal 栏执行 javah -d ./com/lah/studyjni/ com.lah.studyjni.HelloJni 生成 com_lah_studyjni_HelloJni.h 文件。

留意下, -d 是指定生成文件的目录,我这里指定到 HelloJni.java 同级目录。

com_lah_studyjni_HelloJni.h 文件完整代码,

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lah_studyjni_HelloJni */

#ifndef _Included_com_lah_studyjni_HelloJni
#define _Included_com_lah_studyjni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_lah_studyjni_HelloJni
 * Method:    setParam
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_lah_studyjni_HelloJni_setParam
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_lah_studyjni_HelloJni
 * Method:    getJniParam
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_lah_studyjni_HelloJni_getJniParam
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

函数名的格式为: Java_包名_类名_方法名。

如 Java_com_lah_studyjni_HelloJni_setParam ,com_lah_studyjni 是包名,HelloJni 是类名,setParam 是方法名 。

3.编写c文件

编写 HelloJni.c 文件,实现 com_lah_studyjni_HelloJni.h 文件中的方法。

#include <jni.h>
#include <stdio.h>

#include "com_lah_studyjni_HelloJni.h"

/*extern "C" */JNIEXPORT void JNICALL
Java_com_lah_studyjni_HelloJni_setParam(
        JNIEnv *env,
        jobject thisObj,
        jstring param) {
    printf("invoke Java_com_lah_studyjni_HelloJni_setParam");
    return;
}

/*extern "C" */JNIEXPORT jstring JNICALL
Java_com_lah_studyjni_HelloJni_getJniParam(
        JNIEnv *env,
        jobject thisObj) {
    char* str = "Hello World from c";
    return (**env).NewStringUTF(env, str);
}

4.编译生成 so 库或 dll

4.1 安装MinGW搭建GCC编译环境

我用的 Windows 。

https://nuwen.net/mingw.html 下载安装包,
在这里插入图片描述
然后安装,指定解压路径,路径自己选,
在这里插入图片描述
还需要将安装目录下 bin 文件夹的路径(我的是 D:\MinGW\MinGW\bin)加入到系统环境变量 path 中。
具体方法是:
依次选择 桌面→ 计算机 → 右键选择属性 → 高级系统设置 → 环境变量 → 系统变量 ,
在 path 变量中加入 D:\MinGW\MinGW\bin; (注意,符号要用英文的)。

安装成功后到控制台执行 gcc -v 查看是否安装成功。
在这里插入图片描述
至此,安装完成。

安装成功后,可以直接在控制台执行 gcc 语句,但是在 IntelliJ IDEA 中执行不了,提示找不到该语句。需要重启电脑才可以在 IntelliJ IDEA中执行 gcc 语句。

4.2 编译生成 dll

dll 用于 Windows 开发环境。

预先在工程目录新建一个 lib 目录存放 dll 文件,这个目录(D:\JetBrains_java_project\src\lib\)后面用到。

在命令行执行如下语句,

gcc --shared -I “D:\Android Studio\jre\include” -I “D:\Android Studio\jre\include\win32” -fPIC D:\JetBrains_java_project\src\com\lah\studyjni\HelloJni.c -o D:\JetBrains_java_project\src\lib\HelloJni.dll

参数说明:

  • gcc --shared -I(大写的 i): --shared 用于生成共享目标文件;-I(大写的 i)用于指定头文件路径

  • D:\Android Studio\jre\include :JDK 路径下 jni.h 文件的路径,不带这个参数会报错 fatal error: jni.h: No such file or directory

  • D:\Android Studio\jre\include\win32 :JDK 路径下 jni_md.h 文件的路径,不带这个参数会报错 fatal error: jni_md.h: No such file or directory

  • -fPIC :暂未知。

  • -o :指定输出文件。

  • D:\JetBrains_java_project\src\com\lah\studyjni\HelloJni.c : 我的工程里,c文件的路径 。

  • D:\JetBrains_java_project\src\lib\HelloJni.dll :生成的 dll 的路径和名称。(需要确保该目录存在)

这样,在 D:\JetBrains_java_project\src\lib\ 目录下就生成 HelloJni.dll 了。

在工程中,选择 Run --> Edit Configuration ,VM option 选项写入 -Djava.library.path=dll文件所在的文件夹路径
在这里插入图片描述
确认,保存,运行。
运行结果,

JniParam:Hello World from c
invoke Java_com_lah_studyjni_HelloJni_setParam

符合预期,成功了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值