linux虚拟机运行c++,C/C++启动Java虚拟机

Android系统基于Linux,它在用户空间的第一个进程是init进程,是属于native性质的进程,但是每个android应用都是跑在虚拟机下边的,第一个虚拟机进程zygote就是被init进程给fork出来的,这就涉及到了如何用native的c/c++代码启动jvm,本文就是做一个小示例来演示一下。

新建一个目录,添加main.cpp,代码如下:

#include

#include

#include

using namespace std;

int main(){

JavaVM* mJavaVM;

JNIEnv* env;

const int size = 3;

JavaVMOption options[size];

options[0].optionString = "-Djava.compiler=NONE";

options[1].optionString = "-Djava.class.path=./"; //指定当前目录为classpath路径

options[2].optionString=  "-verbose:class";

JavaVMInitArgs initArgs;

initArgs.version = JNI_VERSION_1_4;

initArgs.options = options;

initArgs.nOptions = size;

initArgs.ignoreUnrecognized = JNI_TRUE;

if (JNI_CreateJavaVM(&mJavaVM, (void **)&env, &initArgs) != 0) {

cout<

}else{

cout<

jclass startClass =env->FindClass("com/hello/HelloWorld");

jmethodID startMeth;

if(startClass){

cout<

startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");

env->CallStaticVoidMethod(startClass, startMeth, NULL);

}else{

cout<

}

}

return 0;

}

启动jvm需要使用jni中的函数jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args);

第一个和第二个参数都是输入参数,放到函数中被初始化的。第三个参数应传递JavaVMInitArgs结构体的指针,JavaVMInitArgs的定义如下:

typedef struct JavaVMInitArgs {

jint version;

jint nOptions;

JavaVMOption *options;

jboolean ignoreUnrecognized;

} JavaVMInitArgs;

1.version代表jni的版本,我这里填写的是JNI_VERSION_1_4

2.nOptions代表下边的JavaVMOption数组的个数

3.options代表JavaVMOption 数组类型,JavaVMOption的定义为:

typedef struct JavaVMOption {

char *optionString;  /* the option as a string in the default platform encoding */

void *extraInfo;

} JavaVMOption;

4.ignoreUnrecognized值为JNI_FALSE或者JNI_TRUE,如果是JNI_TRUE,那么JNI_CreateJavaVM函数会忽略掉所有无效选项以"-X"或"_"开头的。如果是JNI_FALSE,那么JNI_CreateJavaVM函数遇到无效选项时会返回一个JNI_ERR.

编译main.cpp:main.cpp包含了jni.h,后者又包含了jni_md.h,这两个文件的路径分别如下:/usr/lib/jvm/java-6-sun-1.6.0.26/include

/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux

要使用JNI_CreateJavaVM函数,需要链接libjvm.so动态库,路径如下:

/usr/lib/jvm/java-1.5.0-sun-1.5.0.15/jre/lib/i386/server

因此编译方法如下:

$ g++ -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -L/usr/lib/jvm/java-1.5.0-sun-1.5.0.15/jre/lib/i386/server/ -ljvm main.cpp

在同级目录创建一个java文件HelloWorld.java:

package com.hello;

public class HelloWorld{

public static void main(String[] args){

System.out.println("Hello world from java!");

}

}

编译此文件:$ javac -d . HelloWorld.java

接下来要运行a.out还需一个步骤:修改当前终端的动态链接库环境变量让它能找到libjvm.so.$ export LD_LIBRARY_PATH=/usr/lib/jvm/java-1.5.0-sun-1.5.0.15/jre/lib/i386/server:$LD_LIBRARY_PATH

然后运行 ./a.out会出现输出:创建jvm成功!成功找到类!

Hello world from java!

-------------------启动了java虚拟机以后,如果使用ps命令查看运行的进程,就会发现java虚拟机仍然运行在a.out可执行文件被加载起来的进程中,而且只有java虚拟机退出了,才会继续执行main.cpp剩余的代码。0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值