보통 윈도우용 프로그램을 만들때 delphi 보다는 C 로 만드는 것이 더 편리하거나 , C 로 잘 만들어진 라이브러리 등이 있는 경우 이를 delphi 에서 쓰려고 하면 별도로 DLL 을 만들어야 하는 불편함이 있긴 했습니다.
그러다가 BCC32 를 통해서 볼랜드용 COMF 포맷 OBJ 를 만들어서 delphi 내에서 LINK 하여 사용할 수 있다는 것을 이곳을 통해서 알게 되었습니다.
참조한 곳에서 설명은 command line 을 통해서 빌드하는 방법 이었지만, 이는 BCC32 환경을 구축해야 하는 어려움이 있기 때문에 다목적 컴파일러 IDE 인 CodeBlocks 를 통해서 obj 를 생성하여 delphi 에 link 해 보았습니다.
먼저 제가 사용한 방법은 debug 용 obj 를 통해서 delphi 에서 함께 돌리는 방법이며 , 다음 옵션을 통해서 delphi 내에서 c 코드 디버깅을 함께 할 수 있다는 것을 알았습니다.
요약 하자면,
C calling convention : C 타입 호출 방법 사용 (cdecl 형)
Align data by byte : 1바이트 얼라인먼트
debugging on, inline expansion off : 디버깅을 켬
Include line numbers : 디버깅 정보에 C 코드 라인 정보 추가.
를 포함하여 빌드 하였습니다.
이렇게 할 경우 obj 를 통해 Link 했음에도 , 디버깅시 Trace Into 를 하게 되면 해당 C 코드를 직접 보면서 디버깅이 가능해집니다. (워래 delphi 는 c 코드도 함께 처리 합니다)
예로 제가 자주 쓰는 LZSS 압축 라이브러리를 사용 해 보겠습니다.
먼저 LZSS 라이브러리의 header 정의는 다음과 같이 되어 있습니다.
이제 이걸 delphi 에서 가져다 쓰기 위해서 unit 을 만들면 다음과 같이 됩니다.
여기서 주목해야 할 점은 C 에서 사용하는 몇가지 symbol 을 구현 해 주어야 한다는 점 입니다.
이는 C 의 특성이기도 한데요 , 기본적으로 제가 만들어 쓰는 LZSS 에서는 memset(), memcpy() 을 가장 많이 사용하기 때문에 위 코드에서 처럼 cdecl calling convention 으로 만들어 주었습니다.
일단 위 코드를 수행하기 위해서는 CodeBlocks 와 BCC32 를 통해서 만들어진 obj 를 delphi 코드가 있는 곳에 복사 한 다음,
{$L '오브젝트파일'}
로 선언을 해 주어 , 컴파일 시 링크를함께 할 수 있어야 합니다.
저의 경우는 obj 폴더 뒤에 컴파일된 obj 를 넣었고 위 소스코드처럼 적용 하였습니다.
이렇게 할 겨우 C 로 만들어진 코드를 delphi 에서 별도 DLL 로 로드하여 쓰거나 할 필요 없이, 바이너리 내에 포함 시킬 수 있음은 물론 함께 디버깅을 수행 할 수 있다는 장점이 생기게 됩니다.
또한 malloc() 을 delphi 내에서 정의 해 줌 으로서 delphi 내에서 GetMem 을 사용해서 증감 되는 메모리 카운터를 이용 할 수 있게 됩니다.
단, 중요한 점은 packed record 등의 이유로 반드시 c 코드는 1 바이트 얼라인먼트를 맞춰 주어야 하며, C++ 에서 class 사용은 어려움이 있다는 점 입니다.
bcc32 가 ANSI-C 를 100% 지원 하므로 이런 문제는 잘 만들어진 코드로 인해 잘 피해 갈 수 있겠죠.
요즘 느끼지만, 우리나라에서 인기 없는 delphi 는 잘 쓰면 정말 유연하면서 강력한 개발툴이 라는 점이네요..
윈도우에서는 delphi 가 좀 짱이네요 ^^
-ps-
이어서 샘플로 만든 어플리케이션을 추가 합니다.
간단히 LZSS 알고리즘을 이용해서 압축/해제 하는 프로그램 으로서 확장자가 lzss 인 경우 압축을 해제 하고 아닌경우 압축을 하는 간단한 어플 입니다.
디버깅 정보를 포함 하고 있기 때문에 덩치가 좀 크네요 ..
아래 압축 파일을 받아서 돌려 볼 수 있습니다.