Java中JNI的运用(三)——C/C++中调用Java的方法

Java中JNI的使用(三)——C/C++中调用Java的方法

前面两片文章主要都是自己在实验中,通过Java的native关键字,调用本地的C/C++的Dll库,后面自己想那C/C++能否调用Java中的方法呢?于是网上一搜,还真有这方面的资料,于是乎动手自己也整了个小Demo,具体的原理就不多说了,直接上代码和说明:

1、编写一个Java方法,供C/C++程序调用:

package org.clzps

class HelloTest {
	public HelloTest() {}
	
	public int add(int a, int b) {
		return a + b;
	}
	
	public boolean judge(boolean bl) {
		return !bl;
	}
}

 2、通过javac,编译成HelloTest.class文件,并且通过javap -s -p HelloTest,可得到如下的结果:

Compiled from "HelloTest.java"
class org.clzps.HelloTest extends java.lang.Object{
public org.clzps.HelloTest();
  Signature: ()V
public int add(int, int);
  Signature: (II)I
public boolean judge(boolean);
  Signature: (Z)Z
}

 3、在eclipse-cpp中新建一个C工程,添加src目录,新增jniTest.c的源文件,代码如下:

#include <jni.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>

int main() {
	JavaVMOption options[2];
	JNIEnv *env;
	JavaVM *jvm;
	JavaVMInitArgs vm_args;
	long status;
	jclass cls;
	jmethodID mid;
	jint square;
	jboolean jnot;
	jobject jobj;

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

	vm_args.version = JNI_VERSION_1_6;
	vm_args.nOptions = 2;
	vm_args.options = options;
	vm_args.ignoreUnrecognized = JNI_TRUE;

	status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

	if(status != JNI_ERR) {
		printf("create java jvm success!\n");
		cls = (*env)->FindClass(env, "org/clzps/HelloTest");
		if(cls != 0) {
			printf("find java class success!\n");

			//构造函数
			mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
			if(mid != 0) {
				jobj = (*env)->NewObject(env, cls, mid);
				printf("init ok\n");
			}

			//调用add函数
			mid = (*env)->GetStaticMethodID(env, cls, "add", "(II)I");
			if(mid != 0) {
				square = (*env)->CallStaticIntMethod(env, cls, mid, 5, 5);
				printf("5+5 = %d\n", (int)square);
			} else {
				printf("error\n");
			}

			//调用judge函数
			mid = (*env)->GetMethodID(env, cls, "judge", "(Z)Z");
			if(mid != 0) {
				jnot = (*env)->CallBooleanMethod(env, jobj, mid, JNI_TRUE);
				if(!jnot) {
					printf("Boolean Ok!\n");
				}
			}
		} else {
			printf("find java class failed!\n");
		}
		return 1;
	} else {
		printf("create java jvm failed!\n");
		return -1;
	}
}

 由于需要用到Java中的内容,以及虚拟机等,因此需要在工程进行相应的配置,这里环境是Eclipse IDE for C/C++ Developers,配置如下:

1、选择项目-->properties-->C++ General-->Paths and Symbols;

2、Includes-->GNU C,右侧添加JDK_HOME/include和JDK_HOME/include/win32;

3、Libraries选项卡下,jvm;

4、Libraries Paths下,添加:JDK_HOME/lib;

 

然后,将org.clzps.HelloTest.class复制到C项目下

4、最后运行Build Project,然后Run,结果如下所示:

create java jvm success!
find java class success!
init ok
5+5 = 10
Boolean Ok!

 至此,C/C++调用Java方法成功,仅作自己实验记录,希望能对和我一样刚刚开始学习JNI的人有所帮助!~~