如上,我们已经编写好了CommandExecution.java,现在我们需要编译并生成c语言头文件。
    完整的步骤如下:

    1. cd ./javaweb-sec/javaweb-sec-source/javase/src/main/java/ (换成自己本地的地址)。
    2. vim或编辑器写入./com/anbai/sec/cmd/CommandExecution.java文件(该目录已存了一个注释掉的CommandExecution.java取消掉代码注释就可以用了)。
    3. javac -cp . com/anbai/sec/cmd/CommandExecution.java
    4. javah -d com/anbai/sec/cmd/ -cp . com.anbai.sec.cmd.CommandExecution

    注意JDK版本:
    JDK10移除了javah,需要改为javac-h参数的方式生产头文件,如果您的JDK版本正好>=10,那么使用如下方式可以同时编译并生成头文件。

    1. javac -cp . com/anbai/sec/cmd/CommandExecution.java -h com/anbai/sec/cmd/

    执行上面所述的命令后即可看到在com/anbai/sec/cmd/目录已经生成了CommandExecution.classcom_anbai_sec_cmd_CommandExecution.h了。

    com_anbai_sec_cmd_CommandExecution.h:

    1. /* DO NOT EDIT THIS FILE - it is machine generated */
    2. #include <jni.h>
    3. /* Header for class com_anbai_sec_cmd_CommandExecution */
    4. #ifndef _Included_com_anbai_sec_cmd_CommandExecution
    5. #define _Included_com_anbai_sec_cmd_CommandExecution
    6. #ifdef __cplusplus
    7. extern "C" {
    8. #endif
    9. /*
    10. * Class: com_anbai_sec_cmd_CommandExecution
    11. * Method: exec
    12. * Signature: (Ljava/lang/String;)Ljava/lang/String;
    13. */
    14. JNIEXPORT jstring JNICALL Java_com_anbai_sec_cmd_CommandExecution_exec
    15. (JNIEnv *, jclass, jstring);
    16. #ifdef __cplusplus
    17. }
    18. #endif
    19. #endif

    您可以使用IDE或者vim完成动态链接库的编写,如果您使用MacOS+CLion可能需要把#include <jni.h>改成#include "jni.h",不改也没关系,编译的时候带上库地址就行了。
    头文件命名强制性
    javah生成的头文件中的函数命名方式是有非常强制性的约束的,如Java_com_anbai_sec_cmd_CommandExecution_execJava_是固定的前缀,而com_anbai_sec_cmd_CommandExecution也就代表着Java的完整包名称:com.anbai.sec.cmd.CommandExecution_exec自然是表示的方法名称了。(JNIEnv *, jclass, jstring)表示分别是JNI环境变量对象java调用的类对象参数入参类型
    如果您在不希望在命令行下编译lib,可以参考:Mac IDEA+CLION jni Hello World