前言:以前一直在做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-jni
PUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include
PUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include/darwin)
add_library(java-jni SHARED
java.c)
target_link_libraries(java-jni
jvm)
add_executable(java_jni_sample
java_jni_test.c)
target_include_directories(java_jni_sample
PUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include
PUBLIC /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/include/darwin)
target_link_libraries(java_jni_sample
java-jni
jvm)
二.编写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
六.源代码下载
下载源代码