如上,我们已经编写好了CommandExecution.java
,现在我们需要编译并生成c语言头文件。
完整的步骤如下:
cd ./javaweb-sec/javaweb-sec-source/javase/src/main/java/
(换成自己本地的地址)。- vim或编辑器写入
./com/anbai/sec/cmd/CommandExecution.java
文件(该目录已存了一个注释掉的CommandExecution.java
取消掉代码注释就可以用了)。 javac -cp . com/anbai/sec/cmd/CommandExecution.java
。javah -d com/anbai/sec/cmd/ -cp . com.anbai.sec.cmd.CommandExecution
注意JDK版本:
JDK10移除了javah
,需要改为javac
加-h
参数的方式生产头文件,如果您的JDK版本正好>=10
,那么使用如下方式可以同时编译并生成头文件。
javac -cp . com/anbai/sec/cmd/CommandExecution.java -h com/anbai/sec/cmd/
执行上面所述的命令后即可看到在com/anbai/sec/cmd/
目录已经生成了CommandExecution.class
和com_anbai_sec_cmd_CommandExecution.h
了。
com_anbai_sec_cmd_CommandExecution.h
:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_anbai_sec_cmd_CommandExecution */
#ifndef _Included_com_anbai_sec_cmd_CommandExecution
#define _Included_com_anbai_sec_cmd_CommandExecution
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_anbai_sec_cmd_CommandExecution
* Method: exec
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_anbai_sec_cmd_CommandExecution_exec
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
您可以使用IDE或者vim完成动态链接库的编写,如果您使用MacOS
+CLion
可能需要把#include <jni.h>
改成#include "jni.h"
,不改也没关系,编译的时候带上库地址就行了。
头文件命名强制性
javah生成的头文件中的函数命名方式是有非常强制性的约束的,如Java_com_anbai_sec_cmd_CommandExecution_exec
中Java_
是固定的前缀,而com_anbai_sec_cmd_CommandExecution
也就代表着Java的完整包名称:com.anbai.sec.cmd.CommandExecution
,_exec
自然是表示的方法名称了。(JNIEnv *, jclass, jstring)
表示分别是JNI环境变量对象
、java调用的类对象
、参数入参类型
。
如果您在不希望在命令行下编译lib,可以参考:Mac IDEA+CLION jni Hello World。