문제

델파이, IUnknown 으로 선언:

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

참고: 출력 매개 변수가 형식화되지 않은

TInterfacedObject 하위 난 필요가 처리 QueryInterface, 다,그래서 나는 반환할 수 있는 객체 지원 요청된 인터페이스::

function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
   if IsEqualGUID(IID, IFooBar) then
   begin
      Obj := (TFooBar.Create(Self) as IFooBar);
      Result := S_OK;
   end
   else
      Result := inherited QueryInterface(IID, {out}Obj);
end;

문제는 온 라인:

Obj := (TFooBar.Create(Self) as IFooBar);

델파이 불평:

운영자는 적용되지 않습 이 연산자 종류

분명히 내가 알지 못에 어떻게 또는 무엇을 할당할 out 매개 변수입니다.수은 무작위로도 일,희망에 있는 컴파일러를 중지 불평:

Obj := TFooBar.Create(Self);

Obj := Pointer(TFooBar.Create(Self));

Obj := Pointer(TFooBar.Create(Self) as IFooBar);

을 무시하고 모든 코드를 작성(필요한 경우):를 구현하는 방법 QueryInterface 에는 개체의 후손 TInterfacedObject?


진짜 문제를 해결할 수 있습으로 아래로 삶은 내가 원하는:

내가 원하는 재정의하는 방법에는 인터페이스

에서 동일한 방법:

TList = class(TObject)
...
   function GetItem(Index: Integer): Pointer; 
   procedure SetItem(Index: Integer; Value: Pointer);
   property Items[Index: Integer]: Pointer read GetItem write SetItem;
end;

될 수 있습에 하위 클래스:

TStudentList = class(TList)
...
   function GetItem(Index: Integer): TStudent; 
   procedure SetItem(Index: Integer; Value: TStudent);
   property Items[Index: Integer]: TStudent read GetItem write SetItem;
end;

내가 원하도록 동일한 인터페이스:

IFoo = interface(IUnknown)
...
   function GetItem(Index: Variant): Variant; 
   procedure SetItem(Index: Variant; Value: Variant);
   property Items[Index: Variant]: Variant read GetItem write SetItem;
end;

IFooGuidString = interface(IFoo)
...
   function GetItem(Index: TGUID): string ; 
   procedure SetItem(Index: TGUID; Value: string );
   property Items[Index: TGUID]: string read GetItem write SetItem;
end;

문제는 어떻게 시작할 수 있을 로드하는 내 구현하는 객체:

TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
public
   function IFoo.GetItem = FooGetItem;
   procedure IFoo.SetItem = FooSetItem;
   function FooGetItem(Index: Variant): Variant; 
   procedure FooSetItem(Index: Variant; Value: Variant);

   function IFooGuidString.GetItem = FooGuidStringGetItem;
   procedure IFooGuidString.SetItem = FooGuidStringSetItem;
   function FooGuidStringGetItem(Index: TGUID): string ; 
   procedure FooGuidStringSetItem(Index: TGUID; Value: string );
end;

고 있지 않은 단지 두 가지 방법에 IFoo, 가 6.다음하고 싶은 경우에 다른 추가 지원하는 인터페이스::

IFooInt64String = interface(IFoo)
...
   function GetItem(Index: Int64): string ; 
   procedure SetItem(Index: Int64; Value: string );
   property Items[Index: Int64]: string read GetItem write SetItem;
end;


TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
public
   function IFoo.GetItem = FooGetItem;
   procedure IFoo.SetItem = FooSetItem;
   function FooGetItem(Index: Variant): Variant; 
   procedure FooSetItem(Index: Variant; Value: Variant);

   function IFooGuidString.GetItem = FooGuidStringGetItem;
   procedure IFooGuidString.SetItem = FooGuidStringSetItem;
   function FooGuidStringGetItem(Index: TGUID): string ; 
   procedure FooGuidStringSetItem(Index: TGUID; Value: string );

   function IFooInt64String.GetItem = FooInt64StringGetItem;
   procedure IFooInt64String.SetItem = FooInt64StringSetItem;
   function FooInt64StringGetItem(Index: Int64): string ; 
   procedure FooInt64StringSetItem(Index: Int64; Value: string );
end;

고 일을 정말로 다루기 힘든 매우 빠르다.

도움이 되었습니까?

해결책

을 입력 할 필요가-캐스팅 측정의 문입니다.는 방법,형식화되지 않은 매개변수 유형,컴파일러는 방법을 알고 있는 값을 할당합니다:

IFooBar(Obj) := TFooBar.Create(Self) as IFooBar;

참고는 당신이 중 하나를 깨뜨리 의 요구 사항 COM.는 경우 쿼리를 위한 인터페이스,당신이 할 수 있어야한 쿼리에 대한 결과 IUnknown 과 항상 같은 값을 얻:

Foo.QueryInterface(IUnknown, I1);
I1.QueryInterface(IFooBar, B);
B.QueryInterface(IUnknown, I2);
Assert(I1 = I2);

하려면 새로 생성 개체를 유형의 TFooBar,다음을 제공하는 인터페이스 방법을 생성하는 사람들:

function TFoo.NewFooBar: IFooBar;
begin
  Result := TFooBar.Create(Self) as IFooBar;
end;

다른 팁

외의 강탈의 발언의 규칙을 여기에서,당신은 수도 성공과 함께 이를 구성:

function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
   if IsEqualGUID(IID, IFooBar) then
      Result := TFooBar.Create(Self).QueryInterface(IID, obj)
   else
      Result := inherited QueryInterface(IID, {out}Obj);
end;

내가 이것을 조사하지 않았지만,당신이 얻을 수 있습니다 몇몇 문제들을 참조 계산...

의 구현을 기반으로 TObject.GetInterface 에서는 시스템입니다.pas I would suggest this:

  Pointer(Obj) := TFooBar.Create(Self);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top