Chinaunix首页 | 论坛 | 博客
  • 博客访问: 347034
  • 博文数量: 42
  • 博客积分: 1896
  • 博客等级: 上尉
  • 技术积分: 615
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-19 14:47
文章分类

全部博文(42)

文章存档

2012年(1)

2011年(21)

2010年(16)

2009年(4)

分类:

2009-06-24 13:58:22

最近需要使用XUL和XPCOM实现一个资源管理器,允许用户添加收藏的系统文件夹和现实用户在服务器端的网络文件夹。实现方式:界面使用XUL的tree,数据源用RDF。由于mozilla的RDF的数据源组件中有一个内置的rdf:files组件,用于访问本地的文件系统,所以为了简化实现,我们在实现收藏功能的时候使用组合RDF数据源格式,只添加一个描述收藏文件关系的一个RDF和rdf:files作为组合数据源为tree提供数据,为了使用rdf:DSName这种URI方式来通过RDFService来访问我们的数据源,我用JS写了一个实现nsIRDFDataSource接口的XPCOM组件,代码简单,写完后进行测试!发现每次打开C盘根目录就FF崩溃,但是如果使用rdf文件的格式和rdf:iles进行组合却没问题,百思不得其解,只好编译了一个debug版本的xulrunner来调试。查看调用堆栈,发现崩溃发生在组件"@mozilla.org/rdf/container-utils;1"的IsEmpty方法中(源码位置:mozilla\rdf\base\src\nsRDFContainerUtils.cpp),原来该函数内部GetTarget函数返回的指针时,只检查nsresult返回值,并未检查指针,对null指针进行调用,引发崩溃。然后我在函数内部添加一个检查指针的语句,编译,运行,OK,不崩溃了,内心窃喜,以为发现mozilla源码中一个bug,就屁颠屁颠跑去google中rdf group发了个帖子。但是仔细一想,人家mozilla有很多这类组件,如:rdf:files,rdf:history,为什么人家不会崩溃呢?然后我去看这些组件实现的代码,调试,发现IsEmpty函数调用内置组件的的GetTarget函数的时候如果指针为空,则nsresult返回值也为非0,所以函数退出,不会出错。但是调用我的组件缺指针为null是nsresult也为0,我就纳闷,我不就转调了一个xml RDF DS组件的这个方法吗,为什么就不一样了。继续阅读代码,发现当GetTarget返回值为null,在C++的组件中均返回NS_RDF_NO_VALUE,而该宏是使用NS_ERROR_GENERATE_SUCCESS定义的,按理CPP中的错误返回值会当成异常抛到JS中,但是我的js组件根本未捕获到异常,我就判断NS_ERROR_GENERATE_SUCCESS定义的返回值并不作为异常抛出,这时mozilla牛人Neil专家给我回帖了,果然如此!NS_RDF_NO_VALUE只能在C++代码中被获取,在js实现的XPCOM组件无法获取。类似情况在很多C++实现的组件中都有,很多在C++中非0的返回值无法传递到JS中,所以在我们实现JS的XPCOM的时候如果是通过转调这些组件的接口来实现自己的接口的时候需要自己检查返回值的是否为空,然后再使用Components.results.NS_ERROR_*的方式抛出,防止在mozilla的组件在调用的我们的JS组件的时候发生类似崩溃!
阅读(1112) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~