XE2中将IDispatch转换时发生访问冲突

3

我们正在使用一些旧代码(由Binh Ly创建的ComLib.pas),以便我们可以在(OleVariant)对象上使用枚举接口:

type
  TDispNewEnum = dispinterface
    ['{97079E31-6957-11D2-9154-0000B4552A26}'] // dummy
    property _NewEnum: IUnknown readonly dispid -4; // DISPID_NEWENUM
    function _NewEnumFunc: IUnknown; dispid -4; // DISPID_NEWENUM
  end;

procedure TEnumVariant.AttachUnknown (const Unk: IUnknown);
var
  pDisp: IDispatch;
  _NewEnumPropFailed: boolean;
  Unknown: IUnknown;
begin
  Detach;
  Unknown := Unk;
  { extract IEnumVariant }
  if (Unknown <> nil) then
  begin
    { try IEnumVariant }
    if not (Succeeded (Unknown.QueryInterface (IEnumVariant, FEnumVariant))) then
    begin
      FEnumVariant := nil;  // safety!

      { test _NewEnum prop and _NewEnum func }
      if (Succeeded (Unknown.QueryInterface (IDispatch, pDisp))) then
      begin
        _NewEnumPropFailed := False;
        try
          //property _NewEnum
          Unknown:=TDispNewEnum(pDisp)._NewEnum; // <---- RAISES EXCEPTION -----
          if not (Succeeded(Unknown.QueryInterface(IEnumVariant, FEnumVariant))) then
            FEnumVariant := nil;  // safety!
        except
          _NewEnumPropFailed := True;
        end;  { except }

这段代码可以在Delphi 2010和2007上运行,但不能在XE2上运行。在标有“RAISES EXCEPTION”的行(注释中),我们会收到异常:

项目x.exe引发了异常类$C0000005,消息为“访问地址0xbaadf00d时出现访问冲突”。

传递的对象确实具有TDispNewEnum接口,因此不应引发异常(与Delphi 2010和2007的情况相同)。
有什么建议吗?谢谢。

请参考 https://dev59.com/NWsz5IYBdhLWcg3wcnhb 了解可能出现的根本原因问题。看起来明显是一个退化问题。 - Arnaud Bouchez
1个回答

5
"0xbaadf00d" 内存地址是一个伪内存地址,意思是“BAD FOOD”(看十六进制字符)。通常当您请求无效接口或调用时,代码会使用它。
如果您将该行更改为:
pDisp: TDispNewEnum;
...
if (Succeeded (Unknown.QueryInterface (IDispatch, pDisp))) then
begin
   _NewEnumPropFailed := False;
   try
     //property _NewEnum
     Unknown:= pDisp._NewEnum; 
...

我觉得这更有意义。

我注意到XE2界面绑定中有一些未记录的更改。也许之前使用强制类型转换(TDispNewEnum(pDisp))的代码由于这个原因不再起作用。


我已经使用了" FEnumVariant:=IUnknown(UnkV._NewEnum)作为IEnumVariant"包含在try / except中,它似乎正在工作。 - Mick
@Arnaud,我目前在XE2和基于Add-In Express的Excel插件上遇到了问题。当编译XE2中的调用2010中有效的Excel COM接口时,现在会失败。我怀疑XE2的COM层是发生了变化,而你在这个答案中的评论让我怀疑你的观察结果与我的问题有关。你是否已经撰写关于XE2和COM的发现的内容? - David Heffernan
3
这听起来就像是https://dev59.com/NWsz5IYBdhLWcg3wcnhb中所述的一样。 - Arnaud Bouchez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接