델파이로 개발해보신 분이면, 이따금씩 오브젝트 파스칼의 initialization/finalization 문법이 얼마나 편리한지 아실 겁니다.
initialization/finalization은 오브젝트 파스칼에서 interface/implementation 과 마찬가지로 소스상의 섹션인데요.
initialization은 해당 소스를 포함한 모듈이 로딩될 때(exe든 dll/bpl이든) 무조건 호출되는 루틴들을 지정할 수 있고,
finalization은 반대로 해당 모듈이 언로딩될 때 무조건 호출되는 루틴들을 지정합니다.
어쩌면 이해를 못하실 수도 있는데..
이해가 잘 안되시는 분들은 이런 문법에 대해 필요성을 느끼지 못한 것이니 그다지 신경쓸 필요가 없을 듯. ^^
VCL의 소스를 보신 분들은 볼랜드의 개발자들이 VCL에서 이 initialization/finalization 문법을 얼마나 요긴하게 잘 활용
했는지 아실 겁니다. dll이나 bpl을 개발하는 경우 초기에 무조건 실행될 루틴을 지정하려면 C++에서는 DllEntryPoint를
이용할 수 있기는 하지만 반대로 언로딩될 때 호출될 루틴은 지정할 방법이 마땅치 않습니다.
마침 제가 C++빌더와 델파이 양쪽 모두에서 사용 가능한 이런 문법이 필요해서 여기저기 뒤져봤습니다.
그랬더니 두가지 방법이 나오더군요.
첫번째 방법은 #pragma startup과 #pragma exit를 이용하는 것입니다.
void Initialize(void)
{
ShowMessage("Initialize");
}
void Finalize(void)
{
ShowMessage("Finalize");
}
#pragma startup Initialize
#pragma exit Finalize
이걸로 끝입니다. 이 소스를 포함한 모듈이 로딩될 때 먼저 Initialize() 함수가 실행되고, 언로딩될 때는 Finalize() 함수가
실행됩니다. [#pragma startup 함수이름] 다음에 우선순위(priority)를 지정할 수도 있습니다.
이 문법에 대해서는 포럼에 예전에 올렸던 담비님의 다음 글에도 설명되어 있더군요.
(구글링을 해서 해외 사이트에서 찾고 나니 역시 구글에 포럼의 글도 검색되어 나오더군요.)
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=106
또다른 한가지 방법은 전역 클래스 객체의 생성자/파괴자에서 처리하는 방식입니다.
VCL 기반이 아닌 C++ 클래스를 하나 만들고 생성자/파괴자를 만듭니다. 그리고 해당 클래스의 객체를 (포인터가 아니라)
객체 자체를 정적으로 생성하면 됩니다. 해당 모듈이 로딩될 때 정적으로 선언된 해당 클래스 객체가 생성되고 따라서
생성자가 호출되므로 여기서 초기화 루틴을 호출하면 됩니다. 또한 역시 해당 모듈이 언로딩될 때 해당 객체가 파괴되므로
파괴자에서 종료 루틴을 호출하면 되지요.
class TInit
{
public:
TInit()
{
Initialization();
}
~TInit()
{
Finalization();
}
static void Initialization();
static void Finalization();
} Init;
// YOUR UNIT BODY
void TInit::Initialization()
{
// Enter your initialization code here
}
void TInit::Finalization()
{
// Enter your finalization code here
}
(위 코드는 Gabriel Kamenov이라는 분이 뉴스그룹에 올린 예제 코드입니다)
참고로, 저는 첫번째 방법, 그러니까 #pragma startup / #pragma exit 방식을 선택했습니다.
초기화/종료 루틴만을 위해 정적 객체를 하나 생성한다는 것이 왠지 맘에 안들고 또 첫번째 방식이 좀 더 코드가 간소해서요.
하지만 하는 역할은 동일하므로 원하시는 대로 방법을 선택해서 쓰시면 되겠습니다.
그럼...
좋은 정보 감사합니다~