简体   繁体   English

访问冲突在XE2中强制转换IDispatch

[英]Access violation casting IDispatch in XE2

We're using some old code (ComLib.pas created by Binh Ly) so we can use the enumeration interface on an (OleVariant) object: 我们正在使用一些旧代码(由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 }

This code is working on Delphi 2010 and 2007, but not with XE2. 此代码适用于Delphi 2010和2007,但不适用于XE2。 On the line marked above (with the comment "RAISES EXCEPTION"), we get an exception: 在上面标记的行上(注释“RAISES EXCEPTION”),我们得到一个例外:

Project x.exe raised exception class $C0000005 with message 'access violation at 0xbaadf00d: read of address 0xbaadf00d'. Project x.exe引发了异常类$ C0000005,并显示消息'0xbaadf00d的访问冲突:读取地址0xbaadf00d'。

The object passed in does have the TDispNewEnum interface so no exception should be raised (as is the case with Delphi 2010 and 2007). 传入的对象确实具有TDispNewEnum接口,因此不应引发任何异常(与Delphi 2010和2007的情况一样)。

Suggestions? 建议? Thanks. 谢谢。

The 0xbaadf00d memory address is a pseudo memory address, meaning "BAD FOOD" (look at the hexa chars). 0xbaadf00d内存地址是伪内存地址,意思是“BAD FOOD”(查看hexa chars)。 This is used usually by code when you ask for invalid interfaces or calls. 当您要求无效的接口或调用时,通常由代码使用。

What if you change the line into: 如果将行更改为:

pDisp: TDispNewEnum;
...
if (Succeeded (Unknown.QueryInterface (IDispatch, pDisp))) then
begin
   _NewEnumPropFailed := False;
   try
     //property _NewEnum
     Unknown:= pDisp._NewEnum; 
...

which makes better sense to me. 这对我来说更有意义。

I've noticed some undocumented changes in the XE2 interface binding. 注意到 XE2接口绑定中有一些未记录的更改。 Perhaps the previous code with a forced typecast ( TDispNewEnum(pDisp) ) is not working any more because of that. 也许以前使用强制类型转换的代码( TDispNewEnum(pDisp) )因为这个原因而无法正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM