Java语言分为编译和运行两个阶段。
第一个阶段是使用javac命令完成的,第二阶段是使用java命令完成的。
下面的目标就是写一个java程序,然后手动创建一个Java虚拟机实例来执行该java程序。
创建一个Demo.java文件
public class Demo {
public static void greet(String name) {
System.out.print("Hi! "+name);
}
}
对上面程序进行编译,得到一个Demo.class文件
javac Demo.java
下面写一个C++程序jvmdemo.cpp来启动一个虚拟机并且执行上面的字节码程序。
#include <jni.h>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv) {
// 1、生成Java虚拟机参数
JavaVMOption jvmopt[1];
jvmopt[0].optionString = "-Djava.class.path=.";
JavaVMInitArgs vmArgs;
vmArgs.version = JNI_VERSION_1_2;
vmArgs.nOptions = 1;
vmArgs.options = jvmopt;
vmArgs.ignoreUnrecognized = JNI_TRUE;
// 2、生成虚拟机
JavaVM *javaVM;
JNIEnv *env;
long flag = JNI_CreateJavaVM(&javaVM, (void**)&env, &vmArgs);
if (flag == JNI_ERR) {
cout << "Error creating VM. Exiting...\n";
return 1;
}
// 3、查找并加载类
jclass jcls = env->FindClass("Demo");
if (jcls == NULL) {
env->ExceptionDescribe();
javaVM->DestroyJavaVM();
return 1;
}
// 4、greet()方法的ID
if (jcls != NULL) {
jmethodID methodId = env->GetStaticMethodID(jcls,
"greet", "(Ljava/lang/String;)V");
if (methodId != NULL) {
jstring str = env->NewStringUTF("Hello");
// 6、greet()方法
env->CallStaticVoidMethod(jcls, methodId, str);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
}
}
// 7、销毁Java虚拟机
javaVM->DestroyJavaVM();
return 0;
}
编译C++文件
Linux平台下:
g++ -IC:/java/include -IC:/java/include/win32
-o jvmdemo jvmdemo.cpp C:/java/lib/jvm.lib
运行:
./jvmdemo
如果出现下面错误,可以参考下面的解决方案
error while loading shared libraries: libjvm.so: cannot open shared object file: No such file or directory
http://blog.csdn.net/zhangmingbao2016/article/details/52786056
参考文章:
https://www.developer.com/java/data/how-to-create-a-jvm-instance-in-jni.html
http://blog.csdn.net/dr8737010/article/details/8504093