지금으로부터 무려 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 |
댓글