길주석 님이 쓰신 글 :
: 아래와 같이 선언유닛에 하나의 buttonclick메소드를 만들어 두고(`method`라는 문자열을 보여주는)
:
: 다른 폼에서 버튼을 누르면 그 메소드가 사용되게 하는 것입니다.
:
: 저의 소스로는
:
: [DCC Error] Unit13.pas(31): E2009 Incompatible types: `method pointer and regular procedure`가 나옵니다
:
: 검색해보니 메쏘드를 등록하려면 메소드타입(of object)으로 해야한다는 것 같은데 저의 소스로 예제하나 작성
:
: 해 주실분 계실까요
:
: --사용할 폼
: procedure TForm13.FormCreate(Sender: TObject);
: var CM : TCM;
: begin
: cm:=abcde;
: Button1.OnClick:=cm;
: end;
:
: --선언하는 유닛(공용유닛)
: type
: TCM = procedure ();
: procedure abcde ();
:
: implementation
:
: procedure abcde ();
: begin
: Showmessage(`Method`);
: end;
OnClick 이벤트 핸들러는 TNotifyEvent 타입으로 정의되어 있고...
TNotifyEvent 는 일반적인 함수포인터와는 달리, 클래스 메소드에 대한 함수포인터이기 때문에
OnClick 에 지정할 수 있는 함수는 클래스 메소드라야 합니다.
일반적인 함수 포인터일 경우 32비트 환경이라면 4바이트 크기의 주소를 담을 공간만 필요하지만
TNotifyEvent 와 같은 클래스 메소드 포인터는 4바이트 크기의 함수 주소와 함께, 클래스 객체를 가리키는
this 포인터(델파이에서는 Self)도 같이 저장되어야 하는 타입이라는 거죠. (컴파일러가 코드를 생성할 때
클래스 메소드의 주소는 물론, 객체의 Self 포인터도 같이 할당하도록 코드를 생성 하게 됩니다)
클래스 메소드 포인터 타입인 TNotifyEvent 는... C++로 표현하면.. 다음과 같이...
typedef void __fastcall (__closure *TNotifyEvent)(System::TObject* Sender);
일반적인 함수 포인터가 아니고 __closure 키워드로 컴파일러에 의해서 특별히 취급되는 클래스 메소드
포인터 입니다.
C# (csharp) 같은 언어는 클래스 메소드는 물론, static 메소드 까지 처리 할수 있도록 언어가 확장되어
있지만... 델파이나 C++ 빌더에서 델리게이트 모델은 클래스 메소드만 사용할 수 있습니다.
|