【混合编程jni 】第七篇之JNI 的命令行们

277 阅读2分钟

“持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

今天将继续JNI的学习,jni编程中常使用的一些命令行工具如何使用事半功倍,今天就快速的过一下,希望在接下来的使用中可以 发挥效果

javah

javah 是Java 提供的生成jni 头文件的命令行

文件位置 C:\Program Files\Android\jdk\jdk-8.0.302.8-hotspot\jdk8u302-b08\bin

image.png

运行javah

1、将上述路径加入到环境变量path 中

2、打开命令行窗口,直接切换到上面的路径中,执行javah

命令行选项

javah -help

image.png

来个例子:

创建一个项目,创建一个java文件

package jni;
 
public class JniTest {
    //    jni 函数,在C++中实现
    static native int sum(int a,int b);
    public static void main(String[] args) {
    }
}

class 位置 编译之后class的位置,因为我是maven 项目,编译之后class 的位置在target/classes,

不管你的是不是maven项目,总之找到你的class 所在的位置就好

执行命令 切换到项目的顶级包目录下,

执行命令

javah jni.JniTest

其中javah后面的是需要生成头文件类的全路径(包名+类名),当然生成的.h文件位于当前class的目录下。

生成的头文件如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_JniTest */
 
#ifndef _Included_jni_JniTest
#define _Included_jni_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_JniTest
 * Method:    sum
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_jni_JniTest_sum
  (JNIEnv *, jclass, jint, jint);
 
#ifdef __cplusplus
}
#endif
#endif

javap 使用JNI在native内调用java方法时,需要知道java方法的方法签名,

利用javap工具可以方便的生成签名。

由于java方法签名在jni层的表示方法的复杂性,利用这个工具生成签名信息可以避免人工分析带来的错误。

使用方法 javap 的使用和上面的javah 一样,都要加入环境变量path 的路径中

或者直接切换到路径下,或者使用绝对路径,建议加入到path中 image.png

举个例子

因为这里主要说jni的编程,所以这里最重要的一个选项就是-s

用程序生成方法的签名,避免手动去写

同理,切换到classes 所在目录,执行 下面的命令

image.png

descriptor 就是方法的签名,可以用在C++中

nm

给的动态链接库可能因为写错了没有暴露函数,怎么确认函数暴露出来呐、?

Linux 下 nm命令(查看库中函数等)查看so接口信息

nm -D libtestJna.so

window下

需要你安装visual studio,或者下载dumpbin.exe

切换到dumpbin 所在的目录执行

.\dumpbin.exe /exports D:\clion\tett\cmake-build-debug\tett.dll

看下图

image.png

总结

介绍了JNI常用的三个命令

一个是编译生成头文件给c++ javah

一个是生成函数的签名给C++使用 javap

一个是查看C++给的动态库是否包含自己要使用的方法 nm