JNI学习------C语言调用Java (转)

最近项目中需要使用JNI,所以研究了一下,其中遇到过不少问题,总结一下,让遇到同样问题的人可以得到解决。

在C/C++中调用Java的方法一般分为五个步骤:初始化虚拟机、获取类、获取类的方法、创建类对象、调用方法和退出虚拟机。

下面写一个小程序测试一下:

Java代码:

package jni.test;

public class Demo {

	public static int COUNT = 8;

	public String msg;
	private int[] counts;

	public Demo() {
		this("缺省构造函数");
	}

	public Demo(String msg) {
		System.out.println("<init>:" + msg);
		this.msg = msg;
		this.counts = null;
	}

	public String getMessage() {
		return msg;
	}

	public int[] getCounts() {
		return counts;
	}

	public void setCounts(int[] counts) {
		this.counts = counts;
	}

	public void throwExcp() throws IllegalAccessException {
		throw new IllegalAccessException("exception occur.");
	}
}

上面的代码很好理解,我相信你能看的懂,我就不说了。

下面是C语言代码,里面有注释,这里先不详细说明,主要先跑起来再说:

#include <stdio.h>
#include
<jni.h>
#include
<stdlib.h>
#include
<iostream.h>
int main() {
// 定义用到的变量
int res;
JavaVM
*jvm;
JNIEnv
*env;
JavaVMInitArgs vm_args;
JavaVMOption options[
3];
vm_args.version;

// 设置初始化参数
options[0].optionString = "-Djava.compiler=NONE";
// classpath有多个时,用";"分隔,UNIX下以":"分割。
options[1].optionString = "-Djava.class.path=.";
// 用于跟踪运行时的信息
options[2].optionString = "-verbose:jni";
// 版本号设置不能漏
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions
= 3;
vm_args.options
= options;
vm_args.ignoreUnrecognized
= JNI_TRUE;
// 1.初始化虚拟机
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0)
{
fprintf(stderr,
"Can't create Java VM\n");
exit(
1);
}
// 2.获取类
jclass cls = env->FindClass("jni/test/Demo");
// 3.获取类的方法
jmethodID mid= env->GetMethodID(cls,"getMessage","()Ljava/lang/String;");
// 获取Java的构造方法
jmethodID con=env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");
jstring strinit
= env->NewStringUTF("Still is coding!");
jvalue arg[
1];
arg[
0].l = strinit;
//env->AllocObject(cls);
// 4.创建类的对象
jobject obj = env->NewObjectA(cls,con,arg);
// 调用对象的方法
jstring msg = (jstring)env-> CallObjectMethod(obj, mid);

cout
<<msg<<endl;
char *str=(char *)env->GetStringUTFChars(msg,JNI_FALSE);
printf(
"%s===",str);
// 5.退出虚拟机
jvm->DestroyJavaVM();
fprintf(stdout,
"Java VM destory.\n");
return 0;
}

把以上C语言代码用VC6.0打开,然后编译,下面问题就来了,我们一个一个解决。

编译的时候首先会出现如下问题:

错误很明显,我们上面包含了jni.h,但是没找到。这是需要设置一下VC

Tools->Options->Directories,添加JDK安装目录下的两个目录,如图:

同时在Library files中添加JDK下面的LIB目录,如下图:

点击OK完成,重新编译。

好,新问题又来了,看下面描述:

也很明显,说明没有找到jvm.lib。继续设置VCProject->Settings->Link->Object/library modules中把上述路径替换为本机实际安装JDK中的jvm.lib目录,添加完后如下图:

点击OK后重新编译,呵呵,又来问题了,我很高兴啊。

这个问题在网上查了一下,原来是我JDK安装在Program Files下的问题,因为Program Files路径中有一个空格,真郁闷,没办法,只好重装JDK,注意安装目录中不能再有空格了。安装完了,按照上面出现的问题再重新设置一下VC,然后编译,没问题,运行,哇靠,又是一个问题:

这个问题可是花了我大半天时间才搞定的,但其实做法很简单。

看错描述,是没找到jvm.dll,网上很多人说直接找到这个文件把它拷贝到当前目录。但是这种方法不可取,因为jvm.dll这个东东还会依赖其他的文件的,而且它找其它所依赖的文件是通过相对路径找的,你直接就搞这么一个文件出来,其它的也找不到啊。所以这里有一个很好的解决方案,就是把D:\Java\jdk1.6.0_23\jre\bin\client这个JDK下的路径加入Path环境变量,加完之后记得重新用VC打开CPP文件,这个很重要,否则,这个问题还是没有解决。

点击编译,运行,如果出现如下画面,OK,恭喜你,C语言调用Java成功了,下面要做的就是去看代码,并且了解运行的机理了,这个我就不多说了。

源代码下载:http://download.csdn.net/source/3434985

原帖:http://blog.csdn.net/sunchaoenter/article/details/6598719

posted @ 2011-09-03 18:57  zhjb616  阅读(1092)  评论(0编辑  收藏  举报