Q&A

  • DLL에서 컴포넌트 사용 -문자열 전환에서-
30871 질문 개시물과 연관하여 질문 하는 내용입니다.

질문이 너무 뒷쪽에있어 갱신하고자 다시 올리게 되어 죄송합니다.

이중철 님께서 요약을 잘 해주시고 친절히 답변해 주신점 깊이 감사드립니다.
그러나 너무 모르는 터라 예제가 있었으면 좋겠다 생각 하여 부탁 드리고 싶었지만 노력도 하지 않는다고 질책 당할까 두려워(^^) 그러진 못하고 다른 방법(Data Module을 이용한)으로 접근한게 있습니다.

DLL만들어서 테스트를 그런데로 하고 있습니다.^^;

그런데 문제가 생기는 부분이 있는데 시간 되시면 소스좀 검토해 주시기 바랍니다.

※ 문제점 설명

RS232C로 데이터가 수신 될때마다  DataModule에 포함시킨 통신컴포넌트의 RX 이벤트를 이용하여 DLL의 전역변수(strRecv: String;)에 다시 저장하고 외부에서 읽으면 다시 클리어 하는 방식을 사용하였습니다.

그런데 여기서 문제가 발생하였습니다. 데이터가 가끔가다가 사라지고 말아요!

누가 훔쳐가는지 도둑놈을 잡아야 하는데 아무리 소스를 들여다 봐도 잘 모르겠습니다.

DLL의  Function  ComPort_ReadStr():PChar; 의 Return되는 Type을 String으로 하고 Sharemem을 Uses에 포함시키면 (호출하는 프로그램에서도 포함) 100% 데이터가 완벽히 올라옵니다.

이렇게 하게되면 BORLNDMM.DLL 이 파일도 배포를 해야 한다기에 PChar형으로 구현 하고 싶습니다.

PChar 타입을 사용하여도 데이터가 올라올때는 잃어버리지 않고 올라 올때도 있는걸로 봐서는 데이타 형이 완전히 틀린것 같지도 않은것 같습니다.
그냥 제 생각에요!

※ 문제가 되는 프로그램 간추린 부분

*****************************************
************ DLL 부분 ********************
*****************************************
Function  ComPort_ReadStr():PChar;stdcall;
begin
  Result:= DM_Com.ComPort_ReadStr();
end;

*****************************************
******** DataModule의 Unit부분 ***********
*****************************************
  public
    strRecv: String;              //RS232C용 컴포넌트에서 수신된 데이타 저장버퍼
    Function  ComPort_ReadStr():PChar; //외부에서 수신된 데이터를 폴링방식으로 읽을수 있는 펑션 프로토 타입선언
  end;

// 실제 프로그램 되는 부분
Function TDM_Com.ComPort_ReadStr():PChar;
begin
  Result:= PChar(StrRecv);  //PChar로 형변환
  strRecv:= '';   //읽었으니 데이타 수신 버퍼 초기화
end;


// 컴포넌트에서 데이터가 수신될때 발생하는 이벤트 함수
procedure TDM_Com.ComPortRxChar(Sender: TObject; Count: Integer);
var strTemp:string;
begin
  ComPort.ReadStr(strTemp,Count);
  if (length(strRecv) + Count) >= 512 then // 저장버퍼 제한 512byte
    MessageDlg('Receive data overflow error!',mtError,[mbOK],0)
  else
  begin
    strRecv:= strRecv+ strTemp;
  end;
end;


DLL 파트쪽은 이게 다입니다.

아래는 호출하는 프로그램입니다.


*********************************************************
******* DLL을 링크하여 읽어보는 테스트 프로그램***********
*********************************************************
var
  Form1: TForm1;
  Function  ComPort_ReadStr():PChar;stdcall;external 'PRJ_Com.dll';

implementation

{$R *.DFM}

// 타이머를 1ms로 폴링하여 수신된 데이터가 있는지 감시함
procedure TForm1.Timer1Timer(Sender: TObject);
var strTemp: String;
begin
  strTemp:= ComPort_ReadStr(); //위에 DLL에 있는 수신버퍼 읽는함수
  if Length(strTemp) <> 0 then
  begin
    strReceiveData:= strReceiveData + strTemp;
    if (ord(strTemp[Length(strTemp)]) = $FF) then //끝가지 수신
3  COMMENTS
  • Profile
    이중철 2004.03.31 22:01
    안녕하세요 이중철입니다.

    혹시 님 Mobile업체에 근무 하십니까?

    소스를 보니 Terminator 문자 $FF 이고

    클래스가 DM이라고 적혀있는거 보니 그렇게 유추되네요

    제가 그쪽일은 3년간 했거든요 ^^

    위의 최용일님께서 하신 말씀이 맞습니다.
    그러나 제경우에는 그와는 다른 방법을 쓰고 있거든요
    BORLNDMM.DLL 쓰지않고 하는 방법으로서
    첫번째는 콜하는 프로그램의 메모리풀을 쓰는 방법이고
    두번째는 DLL에서 쓰는 방법인데 제경우 TMemoryStream을 사용해서
    해결을 했습니다.

    제가 개선해야 할 부문 몇가지 올리겠습니다.

    1. Timer는 쓰지 않는 방식을 처리하십시요
       (참고로 타이머 1ms 설정한다고 1ms로 작동하지 않습니다)

    2. 메모리풀은 512로 한정되어 있는것은 좀 풀어보세요

    3. 만약 패킷이 혼합되었을때 처리가 없네요
        마지막이 꼭 $FF일 수 없는데
        즉, 두패킷이
  • Profile
    최용일 2004.03.31 20:36
    안녕하세요. 최용일입니다.

    Sharemem유닛을 쓸 경우 이 유닛에서 메모리 관리를 해주니까 괜찮지만...

    그렇지 않을 경우는 문제가 생길 수 있습니다. 때문에 PChar를 사용하시더라도

    직접 메모리를 할당 받아서 리턴값으로 돌려주는게 좋습니다.

    ^^ 항상 즐코하세요...

  • Profile
    배수민 2004.04.01 02:19
    조언 많은 참조 하겠습니다.

    다음에 하면서 발생되는 문제가 있으면 그때 또 도와주시면 고맙겠습니다. 꾸벅 ( _  _)

    그럼 즐코~(저도 써먹어봄) 하세요!
    • 진돌
    • 2004.03.31 22:26
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최수림
      2004.03.31 22:54
      html 파일에서 자바스크립트로 파라미터 값으로 지정해주시면 될거 같은데요
    • 연기훈
      2004.03.31 21:32
      위에서 아래, 좌우 출력이.. 무얼 말습하시는 건지 모르것네요... 종이 방향 가로, 세로 를 말습히시...
    • 전명현
      2004.03.31 22:03
      제 질문이 좀 모호했군요.. 보통은 ColumnHeader, Detail Band 순으로 해서, 위에서 부터 한 줄씩 ...
    • 너구리
      2004.03.31 22:31
      퀵리포트에서는 안될겁니다. 무조건 위에서 아래로 밖에 안되더군요.. 하이퍼 리포트는 되더군요..
    • 민상익
    • 2004.03.31 21:02
    • 1 COMMENTS
    • /
    • 0 LIKES
    • KDDG_BaSTaD
      2004.03.31 21:46
      ==> 쉽게 말하면 델파이에서 DLL 이 나온게 아니라 C 부터 DLL 이 있어와서 그걸 지원하다보니 Delphi...
    • 연기훈
      2004.03.31 20:40
      csv 파일은 일반 text 파일입니다. access나 exel 프로그램에서 바로 변환도 가능하고요.. 프로그램...
    • Robin
    • 2004.03.31 20:26
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2004.03.31 20:32
      안녕하세요. 최용일입니다. 전체화면 얻는것과 같은 방식으로 하시면 됩니다. 단지 DC가 전체화면이 ...
    • 박수영
    • 2004.03.31 19:07
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 박수영
      2004.03.31 19:16
      A테이블의 내용이 B테이블에 그대로 있는 것 같은데 B만 읽어오면 안되나요???? B만 읽어와서 작업이 가...
    • Galaxy
      2004.03.31 20:53
      안녕하세요 답변 감사 합니다. 저도 B만 읽어오면 좋겠지만 현 사항은 그렇지가 않습니다. 아래 테이...
    • 너구리
      2004.03.31 22:25
      오라클에서는 아웃조인이 한쪽으로밖에 걸리지 않습니다. 오라클인거 같은데..어떤디비 인지는 잘모르겠...
    • Galaxy
      2004.04.01 18:17
      답변에 감사 드립니다. 안녕하세요 수고 많습니다. MS-SQL7.0을 사용하고 있습니다. 님의 말씀대로 is...
    • 송태성
    • 2004.03.31 17:54
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 너구리
      2004.03.31 20:18
      TForm.OnActivate, OnDeactivate 는 같은 애플리케이션에서의 폼끼리 활성화,비활성화 될때만 발생을 하구...
    • 송태성
      2004.03.31 22:51
      그대로 코딩했는데도 'IN'은 먹더군요 그런데 모달 폼이라서 그런지 'OUT'  는 안먹더군요.. ...
    • 한원희
      2004.03.31 20:16
      안녕하세요. 한원희입니다. NC(Non-Client) 메시지는 모달폼 외부에 대한 동작으로 발생하는 것이 아니...
    • 송태성
      2004.03.31 22:53
      자세한 답변 감사드립니다. 그런데 말씀하신 방법을 모르겠네요. 일단 제가 필요한 코딩은 모달폼을 ...
    • 루이
    • 2004.03.31 08:37
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 박수영
      2004.03.31 19:21
      for문을 이용을 해서 돌리면서 비교를 하면 안되나요??? tmp := ''; for i := 1 to grid1.rowcount...
    • 너구리
      2004.03.31 22:29
      말그대로 입니다. Statement를 기대했는데 procedure가 나왔넹.. 저에러가 난 뒷부분을 보십시오.. ...
    • 왕초보
    • 2004.03.31 06:30
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 박수영
      2004.03.31 17:54
      datamodule에 연결된 query에다 직접 한번 해보세요... 전 아래와 같이 안 해봐서리...
    • 배수민
    • 2004.03.31 06:22
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 이중철
      2004.03.31 22:01
      안녕하세요 이중철입니다. 혹시 님 Mobile업체에 근무 하십니까? 소스를 보니 Terminator 문자 $FF ...
    • 최용일
      2004.03.31 20:36
      안녕하세요. 최용일입니다. Sharemem유닛을 쓸 경우 이 유닛에서 메모리 관리를 해주니까 괜찮지만... ...
    • 배수민
      2004.04.01 02:19
      조언 많은 참조 하겠습니다. 다음에 하면서 발생되는 문제가 있으면 그때 또 도와주시면 고맙겠습니다. ...
    • 한원희
      2004.03.31 03:24
      안녕하세요. 한원희입니다. 님이 원하시는 것과 동일한 기능을 하는 것이 이미 델파이에 있습니다. bpl ...
    • 이중철
      2004.04.01 03:18
      그런데 문제는 rtl.bpl이 depend 하네요 에궁 rtl.bpl도 같이 까는거 빼고는 거의 문제 없네요 ^^
    • Crazy
      2004.03.31 02:28
      if image1.Picture.Graphic = nil then begin      showmessage( '없음' ); end el...
    • Galaxy
      2004.03.31 18:23
    • 김도형
    • 2004.03.31 00:38
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 연기훈
      2004.03.31 01:38
      흠.. 비트 연산하는 간단한 건데... 델파이로 할려니.. 델파이론 첨이라 맞는지 잘 모르것네요.. 다...
    • 이중철
      2004.03.31 01:53
        cnt - 1   8 - 1 => 7 저도 답변 썼다가 지웠어요 같아서요 ^^
    • 김도형
      2004.03.31 03:16
      맞게 했는지 모르겠는데요... 아래처럼 했는데 계속 ERROR가 나네욤.... =========================...
    • 연기훈
      2004.03.31 20:38
      crc 는 const 에 선언 하는 것이 아니고 var 에서 선언해주어야 합니다. procedure TForm1.Button1...
    • 이중철
      2004.03.31 22:20
      왠만하면 Data : Array of Byte; 이런식 또는 다른것으로 하시기를 아래에 보니 스트링에 해버렸네요 ...
    • goodlsw
    • 2004.03.30 21:40
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 너구리
      2004.03.30 22:18
      재생각엔 그 방식대로 하는건 좋지 않다고 봅니다.
    • 조경모
    • 2004.03.30 21:18
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 박수영
      2004.03.30 21:35
      필드가 숫자형인데 문자를 넣었다거나 아니면 날자의 형식이 다르다거나 한것 같습니다... 우...