前言:以前一直在做Android开发,在某本书上看过一句话“Android上面不只有App类的程序可以运行,能在linux下运行的程序,也可以在Android上面运行”
一.编写C语言部分代码
1.定义java.h头文件
#include <jni.h>#ifndef _JAVA_H_
#define _JAVA_H_int JNICALL JavaMain(void* args);#endif /*_JAVA_H */
2.定义java.c
#include <stdlib.h>
#include <stdio.h>#include "java.h"int JNICALL JavaMain(void* args)
{JavaVM* vm = NULL;JNIEnv* env = NULL;jclass mainClass = NULL;jmethodID mainID;jobjectArray mainArgs;JavaVMInitArgs vm_args;JavaVMOption options[1];options[0].optionString = "-Djava.class.path=.";vm_args.version = JNI_VERSION_1_2;vm_args.nOptions = 1;vm_args.options = options;jint status = -1;printf("JavaMain enter \n");status = JNI_CreateJavaVM(&vm, &env, &vm_args);if (status != JNI_OK){printf("initialize jvm failed \n");return -1;}mainClass = (*env)->FindClass(env, "JavaTest");if (mainClass != NULL){printf("find class ssuccessfully \n");jmethodID mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");if (mainID != NULL){printf("get static method successfully \n");jobjectArray mainArgs;(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);}}if (vm){(*vm)->DestroyJavaVM(vm);}return 0;
}
上面的代码主要分为以下几个部分
- 1.创建java虚拟机
- 2.找到java类
- 3.获取到java的方法
- 4.调用java方法
注意:上面的java类的名字时JavaTest,被调用的方法就是main方法
3.编写可执行文件的java_jni_test.c
#include <stdio.h>#include "java.h"int main(void)
{printf("java-jni-test main \n");JavaMain(NULL);return 0;
}
4.编写编译脚步文件(cmake)
cmake_minimum_required(VERSION 3.18.1)project("java-jni")set(JVM_LIB_PATH /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/jre/lib/server)link_directories(${JVM_LIB_PATH})include_directories(java-jniPUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/includePUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include/darwin)add_library(java-jni SHAREDjava.c)target_link_libraries(java-jnijvm)add_executable(java_jni_samplejava_jni_test.c)target_include_directories(java_jni_samplePUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/includePUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include/darwin)target_link_libraries(java_jni_samplejava-jnijvm)
二.编写java语言部分代码
编写JavaTest.java文件代码
public class JavaTest {public static void main(String[] args) {System.out.println("Test java main Method: say Hello");}
}
三.执行效果如下
四.参考资料
《Java并发编程之美》
Linux上c++通过JNI调用java代码笔记_linux jni c++ 函数传参-CSDN博客
Linux环境中使用JNI实现C语言分别调用 java class 和 java jar-CSDN博客
五.注意事项
1.这个需要先使用命令编译出java文件的class文件出来
javac JavaTest.java
2.在编写java.c文件的过程中,遇到java相关方法的签名,可以执行如下命令(前提是class文件已经生成了)
javap -classpath ./ -s JavaTest
六.源代码下载
下载源代码