Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104573166
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-04-15 18:58:35

     来源:ChinaITLab  

初始化虚拟机

本地代码在调用Java方法之前必须先加载Java虚拟机,而后所有的Java程序都在虚拟机中执行。为了初始化Java虚拟机,JNI提供了一系列的接口函数Invocation API。通过这些API可以很方便地将虚拟机加载到内存中。

创建虚拟机可以用函数

jint JNI_CreateJavaVM
(JavaVM **pvm, 
void **penv, void *args)

对于这个函数有一点需要注意的是,在JDK 1.1中第三个参数总是指向一个结构JDK1_ 1InitArgs, 这个结构无法完全在所有版本的虚拟机中进行无缝移植。在JDK 1.2中已经使用了一个标准的初始化结构JavaVMInitArgs来替代JDK1_1InitArgs。下面我们分别给出两种不同版本的示例代码。

在JDK 1.1初始化虚拟机:

#include 
  int main() {
  JNIEnv *env;
  JavaVM *jvm;
  JDK1_1InitArgs vm_args;
  jint res;
/* IMPORTANT: 版本号设置一定不能漏 */
  vm_args.version = 0x00010001;
/*获取缺省的虚拟机初始化参数*/
  JNI_GetDefaultJavaVMInitArgs
(&vm_args);
  /* 添加自定义的类路径 */
  sprintf(classpath,
"%s%c%s",
  vm_args.classpath,
PATH_SEPARATOR, USER_CLASSPATH);
  vm_args.classpath = classpath;
  /*设置一些其他的初始化参数*/
  /* 创建虚拟机 */
  res = JNI_CreateJavaVM
(&jvm,&env,&vm_args);
  if (res < 0) {
   fprintf(stderr, 
"Can't create Java VM\n");
   exit(1);
  }
  /*释放虚拟机资源*/
  (*jvm)->DestroyJavaVM(jvm);
  }
  JDK 1.2初始化虚拟机:
  /* invoke2.c */
  #include 
  int main() {
  int res;
  JavaVM *jvm;
  JNIEnv *env;
  JavaVMInitArgs vm_args;
  JavaVMOption options[3];
  vm_args.version=JNI_VERSION_1_2;
//这个字段必须设置为该值
  /*设置初始化参数*/
  options[0].optionString
= "-Djava.compiler=NONE";
  options[1].optionString 
= "-Djava.class.path=.";
  options[2].optionString
= "-verbose:jni";
//用于跟踪运行时的信息
  /*版本号设置不能漏*/
  vm_args.version = JNI_VERSION_1_2;
  vm_args.nOptions = 3;
  vm_args.options = options;
  vm_args.ignoreUnrecognized
= JNI_TRUE;
  res = JNI_CreateJavaVM(&jvm, 
(void**)&env, &vm_args);
  if (res < 0)
{
   fprintf(stderr,
"Can't create Java VM\n");
   exit(1);
  }
  (*jvm)->DestroyJavaVM(jvm);
  fprintf(stdout,
"Java VM destory.\n");
  }

为了保证JNI代码的可移植性,建议使用JDK 1.2的方法来创建虚拟机。JNI_CreateJavaVM函数的第二个参数JNIEnv *env,就是贯穿整个JNI始末的一个参数,因为几乎所有的函数都要求一个参数就是JNIEnv *env。

访问类方法

初始化了Java虚拟机后,就可以开始调用Java的方法。要调用一个Java对象的方法必须经过几个步骤:

1.获取指定对象的类定义(jclass)

有两种途径来获取对象的类定义:第一种是在已知类名的情况下使用FindClass来查找对应的类。但是要注意类名并不同于平时写的Java代码,例如要得到类jni.test.Demo的定义必须调用如下代码:

jclass cls = (*env)->FindClass(env,
"jni/test/Demo");
//把点号换成斜杠

然后通过对象直接得到其所对应的类定义:

jclass cls = (*env)-> 
GetObjectClass(env, obj);
//其中obj是要引用的对象,
类型是jobject

2.读取要调用方法的定义(jmethodID)

我们先来看看JNI中获取方法定义的函数:

jmethodID (JNICALL *GetMethodID)
(JNIEnv *env, jclass clazz, 
const char *name,
  const char *sig);
jmethodID (JNICALL *GetStaticMethodID)
(JNIEnv *env,
jclass class, const char
  *name, const char *sig);

阅读(264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~