http://bbs.2ccc.com/topic.asp?topicid=319928
上有网友问我D2009还有什么问题.就简单的说一下我所发现的.
上一段时间一直在用Delphi给其他软件开发一个电子地图的ActiveX控件.
Delphi2009已经出到Update4了.有几个问题一直都还没解决.
1.泛型类库的一处Bug.Generics.Collections.Pas中
constructor TObjectList<T>.Create(AOwnsObjects: Boolean);
begin
inherited;
FOwnsObjects := AOwnsObjects;
end;
如果用这个方法创建TObjectList<T>的话根本不能用.因为父类中根本就没有Create方法参数是boolean类型的.所以父类的构造方法根本就没用被调用到.很多父类成员没创建.所以在IndexOf什么的时候都会报错.
临时的解决方式就是把文件拷贝到工程目录下,把这里的代码改成
constructor TObjectList<T>.Create(AOwnsObjects: Boolean);
begin
inherited Create();
FOwnsObjects := AOwnsObjects;
end;
这个问题我报告给CodeGear.他们也说知道了这个问题.结果Update4发布了,这里还是没有改.
2.就是IDL生成Pascal文件的时候LPSTR翻译到PChar,LPWSTR翻译到PWIdeChar.其实Delphi2009中CHar和WideChar是一个东西.LPSTR应该翻译到PAnsiChar才对.CodeGear只是把以前的Delphi的IDL到Pascal的翻译器拿过来了.这里没有做相应的修改.不知道有没有人报告给过CodeGear.
3.实现Idispatch的时候我不想用TAutoObject的自动化对象.于是使用了TObjectDispatch结合{$METHODINFO ON}编译开关开发.结果发现如果接口本身不在TLB类型库中出现的而是自己代码定义的一点问题都没有.如果接口本身是在TLB中定义的,加上{$METHODINFO ON}的时候编译会报错Internal error HXXXX.XXXX是数字,我记不住了.没法子只能用自动化对象了
4.Themes的单元.finalization节
if not IsLibrary then
InternalServices.Free;
因为ActiveX组件的OCX本身就是DLL.里面用到了界面相关的VCL控件.结果FastMM4就会报InternalServices内存泄露.大概CodeGear的考虑是BPL卸载的时候不要把整个程序的InternalServices卸载掉.但是如果是普通的DLL,OCX则会有造成泄露.
这个问题倒是不大,反正如果不是反复加载卸载就只会泄露一次.不过我还是把它改成
if(InternalServices <> nil) then
begin
InternalServices.Free;
InternalServices := nil;
end;
并把Themes.Pas文件拷贝到当前目录下.这样这个泄露就没有了.
5.AXCtrls.PAS单元.
我是动态创建ActiveX组件的.结果发现创建几个就会有几个TOleLinkStub的泄露.
反复查找到TActiveXControl.Initialize;里面有这样的代码
FOleLinkStub := TOleLinkStub.Create(nil);
FOleLinkStub._AddRef;//增加引用计数
而destructor TActiveXControl.Destroy;里面则是
FOleLinkStub := nil;
这样引用计数也就减到1.永远减不到0.造成泄露.
老办法,把AXCtrls.pas拷贝到当前目录下.
修改代码
I := FOleLinkStub._AddRef() - 1;//取引用计数,调增加方法,返回的就是引用次数
FOleLinkStub._Release; //把刚才增加的引用次数减去
if(I > 1) then
FOleLinkStub._Release;
//
FOleLinkStub := nil;
问题解决.
后来看了一下旧版Delphi的代码,发现4,5的问题一直都存在于VCL类库中.