델파이로 서드파티 컴포넌트의 패키지 프로젝트(.dpk)를 사용자인 개발자가 직접 컴파일할 때, DesignIntf 유닛에서 컴파일러 에러가 나는 경우가 있습니다. 이런 경우에는 흔히 ToolIntf, DesignEditors, Proxies 등의 유닛들도 같이 걸리는 경우가 많습니다.
많은 초중급 델파이 개발자들이, 이런 에러를 만나면 일단 이들 유닛들의 pas 혹은 dcu 파일을 찾아서 해결하려고 접근합니다. 게다가, 열심히 찾는 개발자들의 경우, 그 노력에 부응하듯이, 델파이가 설치된 디렉토리 아래에서 이들 파일들의 pas 소스를 찾아내게 됩니다. 그러면 너무나 당연한 공식처럼, 이 파일들을 찾아낸 개발자들은 패키지 프로젝트에 이들 파일을 추가하거나 혹은 이 파일들을 컴파일한 dcu 파일들을 같은 디렉토리에 두든지 하여 패키지 컴파일시에 링크되도록 합니다.
물론 일반적인 델파이 애플리케이션 개발에서는 대부분 그렇게 시도하는 것이 맞습니다만, 여기서는 아닙니다. 이 유닛들이 사용되는 곳은 컴포넌트 개발 혹은 델파이 IDE 위저드 개발이라고 불리는 특수한 영역입니다.
결론부터 말씀드리자면, 절대로 해당 유닛들의 pas나 dcu를 직접 링크시켜서는 안됩니다. 그리고 그 대신 DesignIde.dcp를 requires 섹션에 추가하여 해결해야 합니다.
그 이유를 설명하자면…
uses에 지정된 파일이 없다고 에러가 났으니 공식처럼 당연히 해당 파일을 찾아야겠다는 시도부터가 시작을 잘못한 것입니다. 델파이에서 uses라는 문법은 반드시 실제 dcu 파일(혹은 pas 파일)을 직접 참조해야만 하는 것이 아닙니다.
DesignIntf를 비롯한 이 파일들은 델파이를 사용하는 개발자들에게는 실질적인 어떤 용도로도 전혀 필요하지 않습니다. 다만 컴포넌트 개발자들이 고급 컴포넌트 개발을 할 수 있도록 볼랜드/엠바카데로에서 참고용으로 소스를 넣어둔 것일 뿐입니다.
DesignIntf, ToolIntf, DesignEditors, Proxies 등의 유닛들은 모두 DesignIde.bpl이라는 패키지에 포함되어 있습니다. 이 bpl을 동적으로 링크하기 위한 일종의 임포트 라이브러리 역할을 하는 것이 바로 DesignIde.dcp 파일입니다. 쉽게 말하면, bpl을 사용하려면 같은 이름의 dcp 파일이 있어야 연동될 수 있습니다. (물론 DLL에 대해 LoadLibrary와 마찬가지로 LoadPackage를 사용하면 bpl을 dcp 없이 직접 링크할 수 있지만 여기서는 논외.)
다시 말하면, 패키지 프로젝트의 requires 섹션에서 DesignIde.dcp를 지정하는 것은 DesignIde.bpl을 동적으로 불러다쓰기 위한 기본적인 준비입니다. 거꾸로 말하면, 해당 루틴을 정적 링크를 할 때에는 dcu 파일을 직접 링크해야 하고, 해당 dcu의 기능을 bpl 패키지의 기능으로 호출하려면 dcp를 requires에 추가하는 것입니다.
그럼, dcu를 링크하나 dcp를 통해 bpl을 동적으로 링크하나 동작은 같을 거라는 얘긴데, 그럼 dcu를 직접 링크해도 되지 않나, 하는 생각을 할 수 있습니다. 하지만 이건 안됩니다.
델파이 IDE 자체를 포함해서, 델파이로 만들어진 애플리케이션의 메모리 공간에서 유닛 이름(네임스페이스 이름)과 클래스 이름은 유일해야 합니다. 따라서 한 유닛이 여러번 로딩되려 할 때는 이름 충돌로 에러가 나게 됩니다. 만약 A.dpk 패키지에서 DesignIntf.dcu를 정적으로 링크해버리면 B.dpk 패키지에서는 DesignIntf.dcu를 링크할 수 없게 됩니다.
델파이 IDE 자체에서는 좀 더 심각한데요. DesignIde.bpl 자체가 이미 델파이 IDE의 메모리에 로딩되어 있으므로, DesignIntf, ToolIntf, DesignEditors, Proxies 등의 유닛 이름들은 이미 로딩된 네임스페이스 이름입니다. 따라서 이들 중 하나의 dcu를 포함한(정적으로 링크한) 다른 bpl 패키지가 로딩되려고 하면 바로 이름 충돌이 일어나므로 해당 bpl은 델파이 IDE에 등록이 불가능합니다.
결국, 다시 말해 패키지 형태로 델파이 IDE에 등록하려는 모든 유닛은 단 하나의 패키지에만 포함되어야 합니다(유일해야 한다는 얘기죠). 컴포넌트 이름도 마찬가지입니다. 그렇지 않으면 해당 유닛을 포함한 두번째 이후의 bpl 패키지는 모두 로딩이 실패하게 됩니다. 로딩이 안되니까 당연히 사용도 불가죠.
이런 이유로, DesignIntf, ToolIntf, DesignEditors 등의 유닛들은 절대로 직접 pas 혹은 dcu를 링크하면 안되고 DesignIde.dcp를 requires 섹션에 추가하는 방법으로만 참조할 수 있는 것입니다.
참고로 말씀드리면…
DesignIde에 포함된 이 유닛들은 모두 컴포넌트 개발시에 델파이 IDE에서 디자인타임 전용 기능을 개발하기 위해 필요한 기능들을 가지고 있습니다. 컴포넌트 에디터, 프로퍼티 에디터, IDE 확장 기능의 위저드 개발 기능 등등이죠.
TComponentEditor , RegisterComponentEditor 쓰려면
Uses절에 DesignEditors ,DesignIntf 를 요구하네요.
(물론, requires에 designide.dcp가 포함되어 있습니다.)
그래서, Uses절에 DesignEditors ,DesignIntf 포함시키고
실제 Compile하고 생성한 Component를 다른 프로젝트에 가져다 쓰면
DesignEditors.dcu가 없다고 나오네요.
뭐가 문제일까요?
여기서 더 못나가네요.