보통 윈도우용 프로그램을 만들때 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 인 경우 압축을 해제 하고 아닌경우 압축을 하는 간단한 어플 입니다.
디버깅 정보를 포함 하고 있기 때문에 덩치가 좀 크네요 ..
아래 압축 파일을 받아서 돌려 볼 수 있습니다.

저작자 표시 비영리 변경 금지
신고
Posted by 견족자K rageworx
  • Favicon of http://amourfou.tistory.com BlogIcon 광란의 사랑
    2010.03.04 09:43 신고

    안녕하세요. ^^
    델파이와 MFC를 연동해서 작업하다 막히는 부분이 있어서 인터넷을 뒤지다 님의 블로그를 발견하게 되었습니다.
    염치불구하고 질문을 올립니다. ^^
    지금 작업하고 있는게 메인 프레임은 델파이로 작성되어 있고, 델파이에서 MFC로 작성된 DLL(확장)을 띄우려고 합니다.
    그래서, 정규DLL 하나 만들어서 델파이에서 정규DLL을 호출하고 정규DLL이 다시 확장DLL을 호출하는 방식으로 구현했습니다.
    그런데, 문제는 이 확장DLL 에서 log10(-1)함수를 쓰는 부분이 있는데 이 부분에서 프로그램이 비정상종료됩니다.
    log10(-1)같은 경우 MFC에서는 -1.#IND 라는 값을 갖게 될 뿐 프로그램이 죽거나 하는 문제는 원래 발생하지 않는데 메인 프레임이 델파이이다 보니 부동소수점연산에서 예외처리가 되어 죽는 것 같습니다.
    log10함수도 어차피 C++의 함수를 사용할텐데 메인 프레임이 델파이라고 그 함수가 부동소수점 연산을 델파이를 따라간가는 게 저도 이해가 가질 않는데 현상은 그렇게 나타나고 있습니다.
    또한 double 값을 0으로 나누는 경우에도 MFC에서는 1.#INF 로 무한대처리가 될 뿐 죽거나하진 않는데요. 델파이에서는 안되는 것으로 알고 있습니다.
    이 부분을 처리할 수 있는 방법이 없을까요?
    물론, 0으로 나누는 문제야 비켜갈 수는 있겠지만, 지금 하고 있는 작업이 수치비교를 위해 log10(-1)부분이 반드시 필요한 코드여서 다른 것으로 대체할 수는 없습니다.
    혹시, 해결방법을 알고 계시면 알려 주시면 감사하겠습니다.

    그럼, 수고하세요. ^^

    • Favicon of http://rageworx.tistory.com BlogIcon 견족자K rageworx
      2010.03.04 17:55 신고

      해당 질문에 대한 답을 다음 링크에 써 놨습니다.
      http://rageworx.tistory.com/838
      찾으시던 답이 맞는거 같은데 ... 도움이 되시길 바래요~