본문 바로가기
프로그래밍/PC

Interface 요약 #3

by 사악신 2012. 4. 19.

지금으로부터 무려 10년전인 2002년 5월경, 델마당 개인게시판에 올렸던 총 9회의 글입니다. 유실된 줄 알았는데 싸이월드 게시판에 있는 걸 확인하고 복구합니다.;;

 

 

 

5. TInterfacedObject

  • IUnknown 인터페이스의 실행부가 작성되어 있음(따라서, TInterfacedObjet를 상속하면 QueryInterface, _AddRef, _Release를 구현해줄 필요가 없음.)
  • system.pas 에 정의됨
TInterfacedObject = class(TObject, IUnknown)
protected
  FRefCount: Integer;
  function QueryInterface(const IID: TGUID; out Obj): HResul; stdcall;
  function _AddRef: Integer; stdcall;
  function _Release: Integer; stdcall;
public
  procedure BeforeDestruction; override;
  property RefCount: Integer read FRefCount;
end;

procedure TInterfacedObject.BeforeDstruction;
begin
  if RefCount <> 0 then Error(reInvalidPtr);
end;

function TInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
const
  E_NOINTERFACE = $80004002;
begin
  if GetInterface(IID, Obj) then Result:= 0 else Result:= E_NOINTERFACE;
end;

function TInterfacedObject._AddRef: Integer;
begin
  Result:= InterlockedIncrement(FRefCount);
end;

function TInterfacedObject._Release: Integer;
begin
  Result:= InterlockedDecrement(FRefCount);
  if Result = 0 then
  Destory;
end;

 

  • InterlockedIncrement, InterlockedDecrement 함수는 쓰레드에서 동기화를 위하여 사용됨

 

6. Interface 의 생성, 사용, 소멸

 

IFormattedNumber = interface
  ['{2DE825C1-EADF-11D2-B39F-0040F67455FE}']
end;


var
  MyNumber: TFormattedInteger;
begin
  MyNumber:= TFormattedInteger.Create(12);
  ShowMessage(MyNumber.FormattedString);
  MyNumber.Free;
end;


var
  MyNumber: IFormattedNumber;
begin
  MyNumber:= TFormattedInteger.Create(12);
  ShowMessage(MyNumber.FormattedString);
end;

 

  • MyNumber 가 객체의 instance 를 담는 포인터가 아니라 인터페이스를 담는 포인터임에 유의!
  • 따라서 MyNumber.SetValue(0) 와 같이 사용할 수 없다.(SetValue 는 TFormattedInteger 객체로 선어되야 사용할 수 있다.)
  • 상기 코드에서 MyNumber는 procedure 의 끝에서 자동으로 메모리에서 해제된다.

 

※ 인터페이스와 참조 계수(Reference Count)

  • 일반적으로 C++(Buider는 제외)에서는 수동으로 AddRef와 Release를 호출하여 참조계수를 처리하지만 델파이는 자동으로 처리한다.
procedure DoSomethingWithInterfaces;
var
  MyIntf: IFormattedInteger;
begin
  MyIntf:= TFormattedInteger.Create(12);
  MyIntf.AddRef;
  ShowMessage(MyIntf.FormattedString);
  MyIntf.Release;

  MyIntf:= TFormattedHexInteger.Create(1024);
  MyIntf.AddRef;
  ShowMessage(MyIntf.FormattedString);
  MyIntf.Release;
end;

 

  • 만약, 기존의 C++ 이라면 상기와 같이 AddRef와 Release를 명시적으로 사용해줘야 한다.
procedure DoSomethingWithInterfaces;
var
  MyIntf: IFormattedNumber;
begin
  MyIntf:= TFormattedInteger.Create(12);
  ShowMessage(MyIntf.FormattedString);

  MyIntf:= TFormattedHexInteger.Create(1024);
  ShowMessage(MyIntf.FormattedString);
end;

 

  • 실제적인 델파이 코드에서는 _AddRef와 _Release 를 사용하지 않아도 된다. 즉, 적절한 시점에 델파이가 자동으로 호출한다.
  • 만약, 강제적으로 인터페이스를 소멸하고 싶으면 MyIntf:= nil; 처럼 하면 된다.

 

반응형

'프로그래밍 > PC' 카테고리의 다른 글

Interface 요약 #5  (0) 2012.04.19
Interface 요약 #4  (0) 2012.04.19
Interface 요약 #2  (0) 2012.04.19
Interface 요약 #1  (0) 2012.04.19
파스칼로 만든 부트로더... - 1 -  (0) 2012.04.09

댓글