Q&A

  • dll에 관하여 질문드립니다.
unit OptoCom;

interface
  type O22_ERROR_CODE = SmallInt;
  type O22HCONT = Cardinal;
  type PO22HCONT = ^O22HCONT;
  type UINT = Cardinal;
  const O22_COM_DUDE_HANDLE_INVALID = 0;
  const MAX_STRING_SIZE = 255;

function O22MdsSendReceSz(hContArg: O22HCONT;
pCommandArg     : Char;
pResponseArg     : PChar;  
cbRespMaxLen0Arg : UINT  ) : O22_ERROR_CODE; stdcall;

implementation
function O22MdsSendReceSz; stdcall; external 'OptoCom.DLL';
end.

여기서 dll 사용을 위하여 interface 와 implememtation 사이에 구현을 했는데
여기다 구현하면 다른 unit에서도 사용할 수 있는것으로 알고 있습니다.
그러면 implementation 밑에 부분은 어떻게 되는 거죠.
실제로 dll의 함수 O22MdsSendReceSz를 사용한다는 선언 부분이것 같은데
이코드도 interface 와 implementation 사이에 들어가야 하는것 아닌가요?
3  COMMENTS
  • Profile
    고지범 2002.09.03 01:23
    external 이라는 키워드를 생각해보시길 바랍니다.

    C/C++ 과 비교해서 생각해보면 (잘 모르셔두 상관은 없습니다.)
    소스코드에서 실행파일을 생성하는 데 다음과 같은 과정을 거칩니다.
    소스코드
      |
    PreCompile
      |
    Compile
      |
    Linking
      |
    실행 파일
    여기서 Compile 과정에서는 실질적인 메모리 주소가 메핑되는 것이 아니라 어디에 있더라 라는 심볼정보가 들어갑니다. Linking 과정에서 정확히 어디~ 라는 것이 매핑되죠.
    델파이 PAS 파일의 interface 부분은 C/C++ 의 헤더 파일(*.h)과 관련있고, implementation 부분은 C/C++ 의 소스 파일 (*.c / *.cpp)와 관련 있다고 생각해보면,
    interface 부분에서 함수를 선언해주는 것은 다른 유닛에서도 참조할 수 있게 하기 위해서 특성을 타지 않는 것이 좋습니다. 즉, 선언하는 함수가 델파이에서 작성된 전역함수인지 아니면 DLL-exported 함수인지 전혀 관계없다는 것이죠.
    implementation 부분은 약간 다른 데, 이 섹션에 들어가는 내용은 위의 생성과정에서 Compile/Linking을 같이 하기 때문입니다. 즉, external 이라는 뜻이 함수의 본체는 현재 정의된 PAS 또는 실행코드 블럭에서 밖에 있다(external 하다, internal 하지 않다)의 뜻으로 해석하시면 될 듯 합니다.
    한가지 더,
    위에서 interface/implementation 부분을 C/C++ 과 비교 했는 데 정확히 등가는 아닙니다. 위와 같은 경우(DLL-exported 함수를 사용하는 경우)는 interface 부분 역시도 Linking 에 참여하게 됩니다.

    예를 들어 comctl32.dll에 들어있는 DllGetVersion 함수를 델파이에서 쓰는 방식은 아래와 같이 3가지나 될 수 있습니다.

      DLLVERSIONINFO = record
        cbSize         :DWORD;
        dwMajorVersion :DWORD;
        dwMinorVersion :DWORD;
        dwBuildNumber  :DWORD;
        dwPlatformID   :DWORD;
      end;
      PDLLVERSIONINFO = ^DLLVERSIONINFO;

    1. interface 부분에 모두 몰아넣는 경우,
    interface
    ...
    function DllGetVersion(a_PassedPointer:PDLLVERSIONINFO):HRESULT;stdcall;external 'comctl32.dll' name 'DllGetVersion';

    2. interface / implementation에 나누어서 넣는 경우
    interface
    ...
    function DllGetVersion(a_PassedPointer:PDLLVERSIONINFO):HRESULT;stdcall;

    implementation
    ...
    function DllGetVersion; external 'comctl32.dll' name 'DllGetVersion';

    3. implementation 부분에 몰아 넣는 경우
    implementation
    ...
    function DllGetVersion(a_PassedPointer:PDLLVERSIONINFO):HRESULT;stdcall;external 'comctl32.dll' name 'DllGetVersion';

    이 방식들 중에서 1, 2번만 다른 유닛에서 참조하여 사용할 수 있습니다.
    델파이 Windows unit의 경우는 2번의 방식만 사용합니다.

    개인적으로는 이런 DLL 사용방식 (보통 static-linking 이라고들 하죠... C++에서 *.lib 파일 사용하는 형식)은 권장하고 싶지 않습니다. 해당 DLL이 없는 경우는 아예 프로그램이 뜨질 않기 때문에... 따라서 개인적으로는 고전적인 LoadLibrary/GetProcAddress/FreeLibrary를 권하고 싶습니다.
  • Profile
    이원상 2002.09.03 02:33
    성의 있는 답변 너무 감사합니다. 이해하는데 많은 도움이되었습니다.
    그리구 동적으로 할당한 이유는 이 함수를 타이머에 넣어서 프로그램의
    종료시까지 사용하는 이유로 한것이 아닌가 생각합니다.
    자주 호출하면 정적으로 할당하는게 맞나요?
  • Profile
    고지범 2002.09.03 03:42
    음 지나가던 얼큰입다... ㅋㅋ 호접한 답변이 도움이 되었다니 넘 기쁩다.
    ^_____^
    정적할당과 동적할당의 구분은 별로 없습니다.
    하지만, 개인적으로는 프로그램의 질의 문제라고 생각합니다.
    가령, 어떤 어플리케이션이 10가지의 일을 할 수 있는 데, 각각의 일의 함수들이 서로 다른 DLL로 되어 있어서 나중에 DLL만 바꾸면 자동으로 프로그램이 업그레이드 되는 어플리케이션이 있다고 가정해보겠습니다.
    사용자가 실수로 10개의 DLL중에서 3개를 지웠다면, 이 프로그램은 동작하지 말아야 하는 가? 아니면 나머지 7가지 기능들만 동작해야 하는 가? 의 문제를 생각해보면 됩니다.
    정적 할당(static linkage)를 사용하는 경우, 위의 예에서 살펴보면, 해당 어플리케이션은 아예 처음부터 동작하지 않습니다. 필요한 DLL을 찾을 수 없다는 빨강 X 표 있는 메시지 박스 띠우고 죽어버립니다.
    동적 할당(dynamic linkage)를 사용하는 경우, 위의 예에서 살펴보면, 어플리케이션을 짜는 프로그래머가 조금만 신경써주면, 없어진 DLL3개에 해당하는 작업을 하려고 할 때, 어떤 이유로 인하여 작업할 수 없다는 메시지를 사용자에게 보여 줄 수 있습니다. 나머지 무사한 7개의 작업의 경우는 사용자에게 어떤 말도 보여주지 않고도 계속 작업을 진행할 수 있는 것이죠. 동적 할당의 경우 프로그램 종료시까지 사용해야 하기 때문에 꺼려진다는 것은 의미가 없습니다. 왜냐하면 Win32에서 프로세스 종료시에 자동적으로 올라가 있던 DLL들이 내려오니깐요... ^^ 동적 할당을 사용하실 때, 해당 함수 포인터를 선언해서 initialization section을 이용하여 GetProcAddress 해 주시면 작업이 편리해 집니다. 즉 해당 함수 포인터를 var 항목에 넣고 그 값을 에러시에 실행되는 함수로 일단 메핑 시켜 놓습니다. 그리고 initialization 항목에서 GetProcAddress를 실행해서 성공하면 함수 포인터를 DLL-함수로 치환합니다. 이런식으로 코딩을 하면 밖에서 호출하는 Unit에서는 해당 함수를 매우 범용적으로 사용할 수 있게됩니다. DLL에러에 대한 대책도 되고요... 물론 이런식으로 개발하는 것은 .NET이 선풍적인 인기를 끄는 이 시점에서 매우 구닥다리라고 생각하지만, 어차피 .NET도 안을 파해쳐보면 COM+ 덩어리이고 COM+ 역시 DLL 베이스니깐...(몬 헛소리 호곡!!!)

    암튼..... 저 개인적으로는 동적할당식으로 작업하는 것이 맞다고 생각하는 부류중에 한명입니다.


    • 전원보
    • 2002.09.03 10:09
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 박장용
      2002.09.03 19:44
      텍스트 파일에 한정된다면 Memo나 RichEdit로 읽어 들이시는게 편합니다.   RichEdit1.Lines....
    • 세균맨
      2002.09.03 19:43
      글쎄요.....특정문자의 인덱스라면 구분자를 말씀하시는 것인지..... 모르겠군요.... 만약 구분자를 말씀...
    • 마니산
    • 2002.09.03 08:55
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2002.09.03 09:19
      안녕하세요. 최용일입니다. 1입니다. 둘다 정수형이고 Byte에서 Integer로 형변환할때 절대 범위를 넘는...
    • sunny
    • 2002.09.03 08:26
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2002.09.03 09:41
      안녕하세요. 최용일입니다. 아래와 같이 해보세요... 좀 더 많이 책보고 VCL에 대해서 공부하셔야 할듯....
    • sunny
      2002.09.03 14:29
      감사합니다. 당장 이렇게 해결하는것만이 최선의 방법은 아닌줄 압니다. 열심히 노력하겠습니다. 그럼...
    • 최용일
      2002.09.03 09:44
      안녕하세요. 최용일입니다. File메뉴에서 프로젝트를 저장하세요... 임의로만든 프로젝트폴더에... ...
    • 한창훈
    • 2002.09.03 07:14
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 이추형
      2002.09.03 23:02
      PL/SQL을 구현해야 하지만 파라독스에서 지원이 되는지는 정확히 모르겠습니다. (오라클등등의 대용량 DB...
    • 배창석
      2002.09.18 08:08
      델파이 소스가 있는 디렉토리의 경로에 '('등의 특수문자가 포함되어있는 지 확인해보세요... 있다면, 제...
    • 이추형
      2002.09.04 01:19
      BDE에서 설정한 Alias name이 'Oracle_DB'인지 확인하시기 바랍니다. 혹 다른이름으로 되어 있는건 아닌지...
    • goodlsw
    • 2002.09.03 05:26
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 한원희
      2002.09.03 05:51
      안녕하세요. 한원희입니다. 캐럿의 위치를 구하기 위해서는 GetCaretPos 라는 API를 사용하시면 됩니다....
    • 김상수
    • 2002.09.03 04:58
    • 8 COMMENTS
    • /
    • 0 LIKES
    • 임형호
      2002.09.03 05:19
    • 김상수
      2002.09.03 05:25
    • 임형호
      2002.09.03 10:37
    • 김상수
      2002.09.03 19:23
    • 임형호
      2002.09.03 22:03
    • 김상수
      2002.09.04 01:45
    • 임형호
      2002.09.04 05:43
    • • • •
    • 한원희
      2002.09.03 05:38
      안녕하세요. 한원희입니다. 서브클래싱이나 윈도우 후킹을 하면 가능할 것 같습니다. 좀 복잡하니까, ...
    • ㄴ ㅏ ㅁ ㅑ
      2002.09.03 19:57
      먼저 답변 감사드립니다 ^o^ procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;  &...
    • 한원희
      2002.09.03 23:49
      안녕하세요. 한원희입니다. 아쉽게도 VK_BACK는 네비게이션 키로 분류되어 있어서 방향키 등과 같이 Key...
    • 임형호
      2002.09.03 05:15
      keypress에서는 잘 모르겠구요. keydown이벤트에서는 if key=46 then   key = 0; ...
    • 김상수
    • 2002.09.03 04:28
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 임형호
      2002.09.03 04:41
      예.. 콤보박스로 그렇게 하면 됩니다.
    • 한원희
      2002.09.03 06:23
      안녕하세요. 한원희입니다. 아래 코드에서 약간 이해가 안가는 부분이 있는데, 수신측에서 데이터의 전...
    • 홍성락
      2002.09.03 06:10
      hsr/////////////////////////////////////////////////// 간단히 DBGrid에 연결된 PopupMenu가 열리는 시...
    • 델파이사랑
      2002.09.03 20:51
      ....^^....^^....^^
    • 고지범
      2002.09.03 03:25
      지나가던 얼큰입니다. 제 생각에는 델파이나 VC++ 이나 가장 좋은 것은 Update Handler 를 이용하는 것이 ...
    • 짱아
    • 2002.09.03 00:55
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 이추형
      2002.09.03 01:21
      TStringGrid.Cells 의 ACol과 ARow를 Loop 돌면서 파일 하나하나 처리 하셔야 할것 같습니다. .. 가장 쉬...
    • 짱아
      2002.09.03 02:37
      ㅡㅡ; 자세히점.. 갈켜 주시겠어염...
    • 고부열
      2002.09.03 03:30
      해당 폼의 버튼 속성중이 Default 가 true로 되어있더군요. 제 친구중에 델파이의 거의 달인이 있는데...
    • 고지범
      2002.09.03 03:44
      클클... 추카합다... 그런 일두 ^^
    • 고지범
      2002.09.03 01:28
      지나가던 얼큰입다. 잘 되는 데요??? KeyDown Event 에서 다음과 같이 하믄... 잘 올라오던디... procedu...
    • 이추형
      2002.09.03 01:28
      procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;   Shift: TShiftState); beg...
    • 고부열
      2002.09.03 01:32
      답변 감사드립니다. // -- 아래는 제가 작성한 소스 코드입니다.       ...
    • 고지범
      2002.09.03 02:11
      윽... MDI child 에서두 잘 들어가 지는 데... 무엇이 다른지 모르겠군요... 테스트를 편하게 하기 위해서...
    • 고부열
      2002.09.03 02:57
      저도 델파이로 프로그램을 3년전부터 하고 있지만 이런 경우는 처음이네요... 아마도... 폼이 생성되...
    • 이경모
    • 2002.09.03 00:04
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 세균맨
      2002.09.03 00:19
      기본적을 원도우에서 지원하는 Port가 있읍니다.. telnet은 23 port, ftp 21 port를 사용하고 있죠. ...
    • 허진
    • 2002.09.02 23:32
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 김용운
      2002.09.10 09:15
      제가 조직도 컴포넌트를 개발하고 있는데 현재는 DB에 있는 자료를 화면에 디스플레이 하는 기능과, 미리...
    • 이추형
      2002.09.03 01:35
      EInvalidOp is the exception class for undefined floating-point operations. Description : EInvali...
    • 이원상
    • 2002.09.02 23:16
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 고지범
      2002.09.03 01:23
      external 이라는 키워드를 생각해보시길 바랍니다. C/C++ 과 비교해서 생각해보면 (잘 모르셔두 상관은 ...
    • 이원상
      2002.09.03 02:33
      성의 있는 답변 너무 감사합니다. 이해하는데 많은 도움이되었습니다. 그리구 동적으로 할당한 이유는 이 ...
    • 고지범
      2002.09.03 03:42
      음 지나가던 얼큰입다... ㅋㅋ 호접한 답변이 도움이 되었다니 넘 기쁩다. ^_____^ 정적할당과 동적할당...
    • 한원희
      2002.09.03 06:38
      안녕하세요. 한원희입니다. TCP를 이용하시는 것이라면, 잘못된 데이터의 전송에 대한 고려를 하지 않으...