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接口就是这么包装过的,不过我还没仔细看。
|

