.通过JNI加载java虚拟机
前面已经分析了java命令加载java虚拟机的方法,即通过JNI和虚拟机交互。因此我们可以很容易的自己写相应的启动代码,实现在C++程序中执行java程序,调用java类的方法。要测试的Java类(Test.java)的代码是:
view plaincopy to clipboardprint?
public class Test {
public Test(){
System.out.println("Test's constructor");
}
public void sayHello(){
System.out.println("Test object say : Hello!");
}
public static int add(int arg1,int arg2){
return arg1 + arg2;
}
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args);
}
}
}
public class Test {
public Test(){
System.out.println("Test's constructor");
}
public void sayHello(){
System.out.println("Test object say : Hello!");
}
public static int add(int arg1,int arg2){
return arg1 + arg2;
}
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args);
}
}
}
加载jvm的C++(StartJVM.cpp)代码如下:
view plaincopy to clipboardprint?
/*
* startjvm.cpp
*
*Created on: 2010-1-28
* Author: Xiutao Zang
*/
#include <iostream>
#include <jni.h>
using namespace std;
int main()
{
JavaVMOption options;
options.optionString = "-Djava.class.path=.";
JavaVMInitArgs args;
memset(&args, 0, sizeof(args));
args.version = JNI_VERSION_1_2;
args.nOptions = 1;
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
JNIEnv *env = 0;
JavaVM *vm = 0;
jint result = JNI_CreateJavaVM(&vm, (void **)&env, &args);
if (result == JNI_OK)
{
cout << "create the jvm successfully!" << endl;
jclass mainClass = env->FindClass("Test");
if (mainClass != 0)
{
cout << "find the main class successfully!" << endl;
jclass stringClass = env->FindClass("java/lang/String");
enum
{
LENGTH = 2
};
const char *mainParams = { "Hello ", "World!" };
jstring jstringTemp;
jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);
for (int i = 0; i < LENGTH; i++)
{
jstringTemp = env->NewStringUTF(mainParams);
env->SetObjectArrayElement(mainArgs, i, jstringTemp);
}
jmethodID mainID = env->GetStaticMethodID(mainClass, "main","([Ljava/lang/String;)V");
if (mainID != 0)
{
cout << "get main method successfully and invoke it!" << endl;
env->CallStaticVoidMethod(mainClass, mainID, mainArgs);
}
else
{
cout << "get main method fail!" << endl;
}
jmethodID methodID = env->GetStaticMethodID(mainClass, "add", "(II)I");
if(methodID !=0){
int sum = env->CallStaticIntMethod(mainClass,methodID,4,6);
cout << "the result of Test.add(4,6) is : " << sum << endl;
}
methodID = env->GetMethodID(mainClass,"<init>","()V");
if(methodID != 0){
jobject res = env->NewObject(mainClass,methodID);
jmethodID objectMethodID = env->GetMethodID(mainClass,"sayHello","()V");
if(objectMethodID != 0){
env->CallVoidMethod(res,objectMethodID);
}
}
}
else
{
cout << "can't find main class!" << endl;
}
cout << "destroy the jvm!" << endl;
vm->DestroyJavaVM();
return 0;
}
else
{
printf("create java jvm fail!\n");
return -1;
}
}
/*
* startjvm.cpp
*
*Created on: 2010-1-28
* Author: Xiutao Zang
*/
#include <iostream>
#include <jni.h>
using namespace std;
int main()
{
JavaVMOption options;
options.optionString = "-Djava.class.path=.";
JavaVMInitArgs args;
memset(&args, 0, sizeof(args));
args.version = JNI_VERSION_1_2;
args.nOptions = 1;
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
JNIEnv *env = 0;
JavaVM *vm = 0;
jint result = JNI_CreateJavaVM(&vm, (void **)&env, &args);
if (result == JNI_OK)
{
cout << "create the jvm successfully!" << endl;
jclass mainClass = env->FindClass("Test");
if (mainClass != 0)
{
cout << "find the main class successfully!" << endl;
jclass stringClass = env->FindClass("java/lang/String");
enum
{
LENGTH = 2
};
const char *mainParams = { "Hello ", "World!" };
jstring jstringTemp;
jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);
for (int i = 0; i < LENGTH; i++)
{
jstringTemp = env->NewStringUTF(mainParams);
env->SetObjectArrayElement(mainArgs, i, jstringTemp);
}
jmethodID mainID = env->GetStaticMethodID(mainClass, "main","([Ljava/lang/String;)V");
if (mainID != 0)
{
cout << "get main method successfully and invoke it!" << endl;
env->CallStaticVoidMethod(mainClass, mainID, mainArgs);
}
else
{
cout << "get main method fail!" << endl;
}
jmethodID methodID = env->GetStaticMethodID(mainClass, "add", "(II)I");
if(methodID !=0){
int sum = env->CallStaticIntMethod(mainClass,methodID,4,6);
cout << "the result of Test.add(4,6) is : " << sum << endl;
}
methodID = env->GetMethodID(mainClass,"<init>","()V");
if(methodID != 0){
jobject res = env->NewObject(mainClass,methodID);
jmethodID objectMethodID = env->GetMethodID(mainClass,"sayHello","()V");
if(objectMethodID != 0){
env->CallVoidMethod(res,objectMethodID);
}
}
}
else
{
cout << "can't find main class!" << endl;
}
cout << "destroy the jvm!" << endl;
vm->DestroyJavaVM();
return 0;
}
else
{
printf("create java jvm fail!\n");
return -1;
}
}
我的运行环境是CentOS,AMD64平台。
相关环境变量:
export JAVA_HOME=/root/DevTools/jdk1.6.0_16
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$JRE_HOME/lib/amd64/server:$JRE_HOME/lib/amd64
编译命令:
g++ -o StartJVM StartJVM.cpp -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -L${JRE_HOME}/lib/amd64/server -ljvm
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ictzxt/archive/2010/01/28/5263750.aspx
页:
[1]