· [Java论坛][安全论坛][数据库论坛][操作系统论坛]
· [专题] IBM Rational高峰论坛 Windows 7十大功能
· [专题] 史上就危险7月 微软 BizSpark 计划介绍
· [IT技术周刊][IT资源下载专区][病毒求助专区]
· [热点] 我也能做CTO_赛迪连载 赛迪七夕特别行动
· [热点] Chrome 4.0采用V8引擎 Java开发编程规范

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

发布时间:2005.04.13 17:25     来源:ChinaITLab    作者:ChinaITLab

异常

由于调用了Java的方法,因此难免产生操作的异常信息。这些异常没有办法通过C++本身的异常处理机制来捕捉到,但JNI可以通过一些函数来获取Java中抛出的异常信息。之前我们在Demo类中定义了一个方法throwExcp,下面将访问该方法并捕捉其抛出来的异常信息,代码如下:























/**
  假设我们已经构造了
一个Demo的实例obj,其类定义为cls
  */
  jthrowable excp = 0;
/* 异常信息定义 */
  jmethodID mid=(*env)->
GetMethodID(env,cls,"throwExcp","()V");
  /*如果mid为0表示获取方法定义失败*/
  jstring msg = 
(*env)-> CallVoidMethod(env, obj, mid);
  /* 在调用该方法后会有一个
IllegalAccessException的异常抛出 */
  excp = (*env)->ExceptionOccurred(env);
  if(excp)
{
  (*env)->ExceptionClear(env);
  //通过访问excp来获取具体异常信息
  /*
  在Java中,
大部分的异常信息都是扩展类java.lang.Exception,
因此可以访问excp的toString
或者getMessage来获取异常信息的内容。
访问这两个方法同前面讲到的
如何访问类的方法是相同的。
  */
  }

线程和同步访问

有些时候需要使用多线程的方式来访问Java的方法。我们知道一个Java虚拟机是非常消耗系统的内存资源,差不多每个虚拟机需要内存大约在20MB左右。为了节省资源要求每个线程使用的是同一个虚拟机,这样在整个的JNI程序中只需要初始化一个虚拟机就可以了。所有人都是这样想的,但是一旦子线程访问主线程创建的虚拟机环境变量,系统就会出现错误对话框,然后整个程序终止。

其实这里面涉及到两个概念,它们分别是虚拟机(JavaVM *jvm)和虚拟机环境(JNIEnv *env)。真正消耗大量系统资源的是jvm而不是env,jvm是允许多个线程访问的,但是env只能被创建它本身的线程所访问,而且每个线程必须创建自己的虚拟机环境env。

这时候会有人提出疑问,主线程在初始化虚拟机的时候就创建了虚拟机环境env。为了让子线程能够创建自己的env,JNI提供了两个函数:AttachCurrentThread和DetachCurrentThread。下面代码就是子线程访问Java方法的框架:

DWORD WINAPI ThreadProc(PVOID dwParam)
  {
  JavaVM jvm = (JavaVM*)dwParam;
/* 将虚拟机通过参数传入 */
  JNIEnv* env;
  (*jvm)-> AttachCurrentThread
(jvm, (void**)&env, NULL);
  .........
(*jvm)-> DetachCurrentThread(jvm);
  }

时间

关于时间的话题是我在实际开发中遇到的一个问题。当要发布使用了JNI的程序时,并不一定要求客户要安装一个Java运行环境,因为可以在安装程序中打包这个运行环境。为了让打包程序利于下载,这个包要比较小,因此要去除JRE(Java运行环境)中一些不必要的文件。

但是如果程序中用到Java中的日历类型,例如java.util.Calendar等,那么有个文件一定不能去掉,这个文件就是[JRE]\lib\tzmappings。它是一个时区映射文件,一旦没有该文件就会发现时间操作上经常出现与正确时间相差几个小时的情况。下面是打包JRE中必不可少的文件列表(以Windows环境为例),其中[JRE]为运行环境的目录,同时这些文件之间的相对路径不能变。

文件名 目录

hpi.dll [JRE]\bin
ioser12.dll [JRE]\bin
java.dll [JRE]\bin
net.dll [JRE]\bin
verify.dll [JRE]\bin
zip.dll [JRE]\bin
jvm.dll [JRE]\bin\classic
rt.jar [JRE]\lib
tzmappings [JRE]\lib

由于rt.jar有差不多10MB,但是其中有很大一部分文件并不需要,可以根据实际的应用情况进行删除。例如程序如果没有用到Java Swing,就可以把涉及到Swing的文件都删除后重新打包。

(T117)

<<上一页 1 2 3 4 5


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· Java语言入门级的十二大特色详细介绍 (04-13) · Java初学者常用开发工具介绍图解 (04-13)
· JAVA程序的反编译 再次掀起编译热潮 (04-12) · 教您怎样部署基于WebSphere的J2EE应用 (04-12)
· 第三次世界大战:论Java世界的分裂 (04-12) · Java开发为什么需要UML?你知道么 (04-12)
· FlashLite与J2ME的全方位分析比较 (04-12) · FlashLite与J2ME的全方位分析比较 (04-12)
· J2ME入门专题系列之三:搭建开发环境 (04-12) · 从C++到Java——理解面向对象的关键所在 (04-12)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
资讯 通信 IT产品 IT技术 信息化
专题:扭亏为盈 联想09年Q2翻番
·专题:Tech·Ed 2009微..
·直播:2009互联网大会..
·迅雷搜狐"互搏" 谁动了..
专题:诺基亚危局已现 或重蹈摩托覆辙
·六股势力角逐4G标准 中..
·专题:联通iPhone并不贵..
·专题:排排坐开商店 三..
商务演示需求分析 多媒体会议室必备投影
·VMware在京隆重举行2009..
·专题:笔记本频道10月热..
·专题:学生机市场 惠普 ..
专题:Tech.Ed 2009微软技术大会
·专题:2009 SYBASE 亚太..
·专题:微软新一代桌面操..
·专题:2009年第3届CSDN..