[新闻] dxpcom v0.1 发布
qiezi
2007-04-16
由于windows上一直遇到DLL加载失败的问题,所以测试是在linux上进行的。
dxpcom v0.1下载地址 包括对xpidl的修改,增加了-m d选项,用来产生d接口。-m dwrap选项还在编写中,生成的代码现在还无法使用。 mozilla/xpcom/*.d大部分是用修改过的xpidl生成的,另有一些是使用htod工具转换的。 有空可以帮我测试一下,目前还不保证转换完全正确,但我大致检查了一下应该没什么问题。要注意的是nsISupports.idl转过来以后要把QueryInterface注释掉,改用mozilla.dxpcom.QueryInterface里面的QueryInterface方法,原因是要与extern(Windows)兼容。 build.sh里面配置的是我自己机器上的一些路径,可以根据自己机器的路径进行修改,这个以后看如何解决,把xulrunner运行库都包进来?挺大个的。。 下一版本(0.2)就是完成xpidl的-m dwrap选项,产生异常风格的D接口。 目前代码中没有包含任何授权声明,0.2版本会选一个协议,不知道哪种好一些,BSD?或是mozilla用的这种?最好是限制少一点的。 这里是里面的一个例子: import mozilla.xpcom.nsXPCOM; import mozilla.xpcom.nsILocalFile; import mozilla.xpcom.nsIComponentManager; import mozilla.xpcom.nsISupports; import mozilla.dxpcom.StringAPI; import mozilla.dxpcom.QueryInterface; import std.string; import std.stdio; void main(char[][] args) { nsIComponentManager componentManager; nsresult result; result = NS_InitXPCOM2(null, null, null); result = NS_GetComponentManager(&componentManager); nsILocalFile ifile = null; result = componentManager.CreateInstanceByContractID( "@mozilla.org/file/local;1", null, &NS_ILOCALFILE_IID, cast(void**)&ifile ); writefln("Create nsIFile instance, result: 0x%08x", result); AString str = new AString("~/dprojects/dxpcom/test.d"w); result = ifile.InitWithPath(cast(nsAString*)str); writefln("InitWithPath, result: 0x%08x", result); long filesize; result = ifile.GetFileSize(&filesize); writefln("GetFileSize result: 0x%08x, filesize: %d", result, filesize); result = NS_ShutdownXPCOM(null); writefln(result); } 这是没有包含返回值处理的。 下一版的异常风格将是这样的: void main(char[][] args) { NS_InitXPCOM2D(null, null); nsIComponentManagerD componentManager = NS_GetComponentManagerD(); nsILocalFileD ifile = cast(nsILocalFileD)componentManager.CreateInstanceByContractID( "@mozilla.org/file/local;1", null, &NS_ILOCALFILE_IID, ); ifile.InitWithPath("~/dprojects/dxpcom/test.d"w); long filesize = ifile.GetFileSize(); writefln("filesize: %d", filesize); NS_ShutdownXPCOMD(null); } 代码可能会有些小变化,大致是这样的。异常风格的接口会放在mozilla.dxpcom里面。使用时可以选择mozilla.xpcom里面返回值风格的接口,也可以选择moaillz.dxpcom里面异常风格的接口,当然也可以混合使用,如果你觉得这样舒服的话。。。 0.3版本的目标是用D编写XPCOM组件,这个可能要修改DMD或GDC来实现,因为XPCOM虚表与COM虚表有一点点不兼容。 |
|
qiezi
2007-04-16
D2.0如果macro功能强大的话,也可以考虑把xpidl现在这个功能做到代码里面去,编译时产生接口。当然这个也要考虑一下编译效率。
|
|
h_rain
2007-04-16
强赞!动作真快!呵呵.
前天晚上我都困糊涂了,也没想清楚. 现在看,接口风格两种就够了,一个使用返回值的标准的仿c++的. 再一个,进行了包装的,使用异常的,方便D中使用的. 关于D写xpcom组件,唯一的障碍就是现在的D的接口模型虚表不兼容. 对了,测试过吗?D写接口,C++调用?也不正常吗? |
|
qiezi
2007-04-16
目前这个IDL转换工具是从xpidl_header上修改的,D接口部分还好,比较简单。异常风格包装部分我自己都看糊涂了,方法签名已经可以转换了,还剩下方法实现里面的类型转换、调用转换和返回值转换要做,得花点时间整理一下代码。。。
用D写XPCOM,如果虚表问题解决了,可以直接使用返回值风格的接口来编写。异常风格需要再写一个生成器来做,不过转换方法前面的讨论里面都已经确定了,所以剩下的是工作量的问题。用C写这些还真是麻烦,怎么libIDL没有脚本语言的封装呢。。 XPIDL写得也很一般,容错能力极差,自己写的IDL稍有点问题就转换不过,并且报不出错误,还好并不是经常需要用它。所以如果有时间的话宁愿从头用脚本语言来写一个,或者是D语言,不过就怕支持库太少,这需要一个好用点的IDL解析器。 |
|
h_rain
2007-04-16
用D写xpcom组件,只要能提供正确的接口,外面就可以调用了吧?
D里面没必要再弄很复杂的东西了吧? |
|
qiezi
2007-04-16
上面列出了2种D里面调用XPCOM的可能的方式,这里再列一下用D写XPCOM组件的2种方式:
1、返回值风格的,与C++基本一样 class nsLocalFile : nsILocalFile { nsresult QueryInterface(nsIID* iid, void** p) { // 实现代码 } // 实现返回值风格的XPCOM接口 nsresult InitWithPath(nsAString* path) { } } 2、异常风格的 class nsLocalFileD : nsILocalFileD { nsISupports QueryInterface(nsIID* iid) { // 实现代码 } // 异常风格的实现,字符串类型使用的是D内值类型 void InitWithPath(wchar[] path) { } } // 下面部分使用工具生成 class nsLocalFileWrap : nsILocalFile { this(nsILocalFileD inner) { this.inner = inner; } nsresult QueryInterface(nsIID* iid, void** p) { try{ *p = cast(void*)inner.QueryInterface(iid); // 可能还要处理引用计数,防止GC释放掉对象 // 或者做在AddRef和Release里面,但都是工具自动生成 return NS_OK; }catch(XPCOMException ex){ return ex.GetErrorCode(); } } nsresult InitWithPath(nsAString* path) { try{ scope auto _path = new AString(path); inner.InitWithPath(_path.GetString()); return NS_OK; }catch(XPCOMException ex){ return ex.GetErrorCode(); } } private: nsILocalFileD inner; } |
|
qiezi
2007-04-16
一些C++的东西要换掉的,比如字符串,它用的是nsAString,在D里面再实现一个字符串类多痛苦?必须要转换过来。。
|
|
h_rain
2007-04-16
呵呵,我的意思是说,因为是XPCOM组件,对外提供的就是接口,那我们创建D的XPCOM组件的时候,仅仅符合XPCOM的接口规范就可以了,不用再做那么复杂的转换了.
这个对象怎么写都行,只要提供的是标准接口就得了,就是只要有C++返回值风格的接口就够了吧? |
|
h_rain
2007-04-16
因为要转换的这个异常风格的组件是我们自己写的,如果想让工具去自动转换,那又要规定一套规范了.
|
|
qiezi
2007-04-16
这是可以选用的。你可以把返回值风格的接口当作是规范,也可以完全无视它,把异常风格的接口当作是规范。目前xpidl生成的java接口就是这么包装过的,不过我还没仔细看。
|