科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件讲解如何在C/C++中调用Java的方法 (2)

讲解如何在C/C++中调用Java的方法 (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

讲解如何在C/C++中调用Java的方法 (2)

作者:ChinaITLab 来源:ChinaITLab 2007年11月8日

关键字: java 调用 C++ Linux

  • 评论
  • 分享微博
  • 分享邮件

初始化虚拟机

本地代码在调用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 <jni.h>
  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 <jni.h>
  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);
查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章