在 XE2 中铸造 IDispatch 时出现访问冲突

发布于 2024-12-11 20:29:30 字数 1517 浏览 4 评论 0原文

我们使用一些旧代码(由 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,并带有消息“access” 0xbaadf00d 处的违规:读取地址 0xbaadf00d'。

传入的对象确实具有 TDispNewEnum 接口,因此不应引发异常(Delphi 2010 和 2007 就是这种情况)。

建议?谢谢。

We're using some old code (ComLib.pas created by Binh Ly) so we can use the enumeration interface on an (OleVariant) object:

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. On the line marked above (with the comment "RAISES EXCEPTION"), we get an exception:

Project x.exe raised exception class $C0000005 with message 'access
violation at 0xbaadf00d: read of address 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).

Suggestions? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨后咖啡店 2024-12-18 20:29:30

0xbaadf00d 内存地址是一个伪内存地址,意思是“BAD FOOD”(查看十六进制字符)。当您请求无效的接口或调用时,代码通常会使用它。

如果你把这行改成:

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

这对我来说更有意义。

注意到 XE2 接口绑定中存在一些未记录的更改。也许之前带有强制类型转换的代码 (TDispNewEnum(pDisp)) 因此不再起作用。

The 0xbaadf00d memory address is a pseudo memory address, meaning "BAD FOOD" (look at the 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. Perhaps the previous code with a forced typecast (TDispNewEnum(pDisp)) is not working any more because of that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文