[新闻] dxpcom v0.1 发布
h_rain
2007-04-26
嗯.
我的例子也改完了,写个BLOG留念:) |
|
qiezi
2007-04-26
我的在windows上还没办法工作呢。。
|
|
qiezi
2007-04-27
if (ci.flags & 1) // if COM object { p = std.c.stdlib.malloc(ci.init.length); if (!p) _d_OutOfMemory(); } else { p = _gc.malloc(ci.init.length); debug(PRINTF) printf(" p = %p\n", p); _gc.setFinalizer(p, &new_finalizer); if (ci.flags & 2) _gc.hasNoPointers(p); } 这是_d_newclass里面的一段,从COM接口上继承的类没有放入GC。 这是ComObject.Release: ULONG Release() { LONG lRef = InterlockedDecrement(&count); if (lRef == 0) { // free object // If we delete this object, then the postinvariant called upon // return from Release() will fail. // Just let the GC reap it. //delete this; return 0; } return cast(ULONG)lRef; } 只有点注释,谁来真正的delete呢? 看了一下DMD/samples/d/dserver.d,也没有处理,运行dclient,结果析构函数真的没调用呢! 在dclient结束前调用std.gc.fullCollect(),还是一样,在CHello的Release里面把delete this注释去掉,还是不调用! COM对象不能被delete?莫人管了亚! |
|
qiezi
2007-04-27
这个链接有些讨论:
http://www.digitalmars.com/d/archives/digitalmars/D/29146.html 但没有得到Walter回复亚,看样子是要实现者自己去处理。 简单分析了一下,析构函数应该是不会调用的,所以我们要做的析构工作必须在Release里面处理掉,或者D能像C++一样显式地调用析构函数?类似这种:pObj->~Object();这个还不是最重要的,顶多不使用它就行了,把Release当析构函数用,派生类重写它并且调用基类的Release,作为一个规范。 剩下的是对象的析构,可以把COM对象放到一个对象里,这个对象负责释放COM对象使用的内存(前面在_d_newclass里分配的)。这个对象必须放在一个全局的容器里面保持引用,COM对象也引用这个对象。当Release COM对象时,引用计数归0,COM对象把它引用的这个对象从全局容器里拿掉。当这个对象下次被GC回收时,调用析构函数,而析构函数会把COM对象所使用的内存释放掉。 [全局引用容器]<---专门释放COM对象的对象<-----COM对象 | ↑ --------------| 这样子应该是可行的。 用D编写异常风格的XPCOM组件时(简称DXPCOM),该怎么处理呢?这时候接口层的COM对象持有DXPCOM对象,但这个持有不会被GC感知,所以还是需要放到全局容器。COM对象在Release到计数归0时,把DXPCOM对象从容器中拿掉以使其被GC。这时候DXPCOM对象的析构函数是可以被调用的。 这个重要的全局容器可能只需要一个关联数组就行了吧,主要是键查找要快,值则没有什么意义。 |
|
h_rain
2007-04-28
晕~
还真的有点黑啊... COM对象的创建都是使用厂模式吧? XPCOM的组件模型里面,组件有对外提供的管理接口,使用这个管理接口(也是用QueryInterface方法)创建我们的COM对象并返回接口;组件卸载的时候,也是通知管理接口清理组件里面的对象. 就是在我们的接口Release方法中,不能释放自己,因为Release不是析构函数,Release在外面正在被调用,则里面释放自己就会出错. 你上面的思路应该是可以的,不过我觉得应该先看看XPCOM组件提供的工具类是怎么实现的,按照标准的XPCOM组件的创建与管理方法应该就可以吧. 2007-04-30补充:对象删除自己是可以的,只要在这个语句之后再也不要调用指向他的指针。 |
|
qiezi
2007-04-28
DMD里面应该是不会主动释放COM对象的,原因是它根本没在GC里面分配。另外delete一个COM对象也不会调用析构函数,原因是因为没有classinfo所以找不到,这些都是要注意的地方。
当然是按照XPCOM的创建与管理方法,问题在于我们在使用D对象时, 习惯上是创建不删除的,所以需要引入我上面所说的自动管理方式。 |
|
tuja
2007-04-28
qiezi大侠,什么时候写一下 windows com的教程啊。网上 c++关于com的教程很多,难道要先学C再学D吗
你说过IDispatch接口的效率低些,能不能先给个IDispatch接口创建IE实例的例子,感觉D真是好难,没有C++的基础根本无从入手。 虽然D语言本身非常好,但就是一个创建IE实例,我问来问去,官方论坛,新闻组,都没有人能解决。在脚本语言只是一行代码,在D这么难,我现在在看com有关教程,但全是基于C和C++讲解的。唉,要是会C++,也就可能不学D了。 |
|
qiezi
2007-04-28
dsource.org上有这样的例子,我忘记是哪个项目了,你把跟COM相关的项目都下载一下吧,没几个。然后查找里面的IDispatch,找到就看一下就成了。IDispatch主要是Variant类型参数要转换,其它就不麻烦了。最近没有时间,以后有空再做个包装吧。
|
|
oldrev
2007-04-28
D 是为了解决大规模软件开发而诞生的语言,不适合入门也不适合业余消遣
|
|
tuja
2007-04-28
感谢两位的回答。我试试。
|