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 でのアクセス違反: アドレス 0xbaadf00d の読み取り」が発生しました。

渡されたオブジェクトには TDispNewEnum インターフェイスがあるため、例外は発生しません(Delphi 2010 および 2007 の場合と同様)。

提案?ありがとう。

4

1 に答える 1

5

0xbaadf00dメモリアドレスは疑似メモリアドレスで、「悪い食べ物」を意味します (16 進文字を見てください) 。これは通常、無効なインターフェイスまたは呼び出しを要求するときにコードで使用されます。

行を次のように変更するとどうなりますか。

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

それは私にとってより理にかなっています。

XE2 インターフェイス バインディングで、文書化されていない変更がいくつかあることに気付きました。そのため、強制型キャスト ( TDispNewEnum(pDisp)) を使用した以前のコードが機能しなくなっている可能性があります。

于 2011-10-24T12:42:18.497 に答える