· [Java论坛][安全论坛][数据库论坛][操作系统论坛]
· [访谈] 网银安全系列访谈之:惊心动魄网银故事
· [热点专题] 网银安全系列 3G上网卡巡礼
· [订阅IT技术周刊][IT资源下载专区][病毒求助专区]
· [热点] 跨站脚本十二问 四步防范Conficker
· [热点] Windows 7 RC版公开下载 憾缺中文版

讲解如何在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技术 信息化
2009第七届中国电脑商年会直播
·创业投资系列访谈:产业..
·特别策划:视频网站系列..
·专题:网游虚拟货币新规..
专题:6月上市手机新品回顾及7月新机展望
·2009年中国电信业信息化..
·专题:把iPhone 3GS“解..
·WAPI重启国际标准进程 ..
专题:09年中盘点-联想春季打印机新品回顾
·InfoComm 2009 视听与集..
·网游背后的故事 网游服..
·[专题]联想ThinkPad T40..
BizSpark:微软为技术创业企业点燃火花
·社区活动:我的IT求知生..
·访谈:内网安全2009系列..
·安全访谈:网银安全之Sa..