代码部分:
c++:
1,创建JVM环境
注意,如果此时已经有java程序再运行,那么就不能创建了,只能去获取。方法做后续补充。先讲创建。
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
解释:
1),JVM指针 JavaJVM jvm;
2),JNI环境 JNIEnv env;
3),参数指针 JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";// 等号右端的"."表名当前的路径指向的是环境变量classpath
vm_args.version = JNI_VERSION_1_6;// jni版本,一般是低于或者等于当前版本号都可以
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;// 这个值到底会真正影响到哪里,我也不清楚
2,寻找class
当java文件写好之后,可以利用javac命令将其编译为.class文件。在创建JVM环境时,-Djava.class.path=.这个后面可以补充.class文件的路径。
cls = env->FindClass("C2java");,这个类采用的是默认包,可以直接寻找类。返回值为jclass。类似于类的指针,后续对类的操作都是基于它。
cls = env->FindClass("one/two/three/JavaTest");// 这个是含有自定义package的类,类其实为one.two.three.JavaTest。但是在寻找的时候要将"."换成“/”。
3,调用java函数
在dos界面将路径切换到.class文件所在路径,使用Javap -s -p C2Java
mid = env->GetStaticMethodID( cls, "add", "(II)I"); // 调用静态函数,可以直接调用。不需要先new 一个类对象。
if(mid !=0)
{
square = env->CallStaticIntMethod( cls, mid, 5,5);
std::cout << square << std::endl;
}
mid = env->GetMethodID(cls,"<init>","()V"); // 调用构造函数
if(mid !=0)
{
jobj=env->NewObject(cls,mid);
std::cout << "init ok" << std::endl;
}
mid = env->GetMethodID( cls, "judge","(Z)Z");// 这个函数为普通函数,
if(mid !=0)
{
not = env->CallBooleanMethod(jobj, mid, 1); // 需要用过类对象来调用,jobj极为调用构造函数得到的。
if(!not){
std::cout << "Boolean ok" << std::endl;
}
}
mid = env->GetStaticMethodID(cls, "getString", "(II)Ljava/lang/String;");// 使用String麻烦一点
if(mid != 0)
{
jstr = (jstring)env->CallStaticObjectMethod(cls, mid, 2, 3);// 这个是返回值为String
const char* res = env->GetStringUTFChars(jstr, 0);// 需要将返回结果转换成char*,不能直接使用。如果入参为String。
cout << res << endl;// 如果入参是String,那么需要将C++中的char*转换为String。jstring sin = env->NewStringUTF(in);
}
在调用的时候参数以及函数名该怎么写,就按照dos界面提示的那样即可。