Q&A

  • VC++제작 DLL의 WM_COPYDATA 메세지 콜백 관련 시급한 질문이 있습니다. 도와주세요.
VC++제작 DLL의 WM_COPYDATA 메세지 콜백 관련 시급한 질문이 있습니다. 도와주세요.

* WM_COPYDATA 메세지 콜백은 첨이라 고수분들께서 알려주신 것을 기초로 만들어 보았는데
  잘 안되고 있습니다.  도와주시면 고맙겠습니다.

1. VC++로 제작된 DLL파일 : 제공업체로 부터 전달 받음(헤더 파일 포함)

2. 어플리케이션 제작 : 개발환경 델파이 7.0

3. 콜백 방식 :
   - DLL에서 윈도우 메세지(WM_COPYDATA)를 어플리케이션에 전달하여 정보를 전달함
   - 어플리케이션은 DLL의 요청 함수를 호출할 때 콜백 메시지를 받을 윈도우 포인터를 지정
   - DLL에서 SendMessage(WM_COPYDATA, NULL, (WPARAM)pCallbackData) 형태로 전달 함으로
     어플리케이션에서는 콜백 수신 윈도우의 WmCopyData() 함수로 콜백

4. DLL의 vc++ 함수 정의    
   extern "C" __declspec(dllimport)
   INT SOC_InitResponsePacketFunction(CWnd* pCallbackWnd, // [IN] 콜백 수신 윈도우 포인터.
                                                                LPVOID lpUserData = NULL); // [IN] 사용자 지정 포인터.

5. 델파이 어플리케이션 함수 정의
   // 통지 콜백 수신 윈도우 포인터 지정 함수.
   function SOC_InitResponsePacketFunction(
            pCallbackWnd:LongWord;
            lpUserData:Pointer
   ):LongInt;stdcall;external'UserCall.DLL'

6. 적용 델파이 어플리케이션
  .....
  private
    { Private declarations }
    procedure WmCopyData(var MCpyData: TMessage); message WM_COPYDATA;
  .....
  .....
  var
    MyHandle : HWND;

  implementation
  
  // DLL한테 콜백을 위한 윈도우 포인 전달
  procedure TF_AppTest.Button1Click(Sender: TObject);
  begin
    MyHandle := LongWord(@WindowHandle);
    SOC_InitResponsePacketFunction(MyHandle, NIL);
  end;

  // DLL로부터 호출된 콜백 처리부
  procedure TF_AppTest.WmCopyData(var MCpyData:TMessage);
  begin
    // 동작
  end;

7. 테스트 결과
  - 일단 정상 동작을 시작합니다.
  - DLL로부터 10초 간격으로 윈도우 메세지(WM_COPYDATA)가 발생되어
    델파이 어플리케이션 WmCopyData가 정상 동작합니다.
  - 수십번(약60회정도)를 전달받으면 윈도우가 정상동작되지 않습니다.
    (대표증상:익스플로러가 열리지 않음, 윈도우 시작메뉴가 정상동작되지 않음 등 등)
  - Debug용 DLL을 이용하여 확인하여 보니 다음과 같은 에러메세지가 10초마다 발생을 합니다.
  * 에러 창
    제목:MicroSoft Visual C++ Debug Library
    Debug Assertion Failed!
    Program:[어플리케이션 경로 및 실행파일]
    File : afxwin2.inl
    Line : 39
    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation an asserts.
  * Visual C++ 초보자로서 역추적을 하여본 결과 afxwin2.inl의 39라인이 SendMessage부분입니다.
    DLL에서 SendMessage가 호출될 때마다 에러가 나오는 것 같은데.
    또 그로인하여 윈도우가 죽어버리는 현상이 발생하는 것 같은데
    어떻게 잡아야 할 지 통 알수가 없군요..
    정말 정말 저한테는 필요한 사항이니 여러분들의 도움을 요청합니다.

8. 모두 모두 하시는 일 잘 되시기를....  많이 많이 도움을 주십시요.
2  COMMENTS
  • Profile
    타락천사 2007.05.22 19:51
    안녕하세여. 타락임다..

    흠.. 보내는 쪽의 에러로 보입니다..

    한가지 생각나는게 있네요..

    아래가 제가 예전에 썼던 것인데... 보시면 cbData 에 메세지 길이를 넣게 되어 있는데, 메세지 길이 + 1 해서 넣습니다.
    스트링은 "널 종료 문자열" 을 의미하며, 따라서 종료 문자열 까지 포함하여야 하기 때문 입니다..

      nLen := Length(AData) + 1;
      AData := AData + #0;

      with CopyData do
      begin
        cbData := nLen;
        lpData := pChar(AData);
      end;

      SendMessage(FhServer, WM_COPYDATA, 0, LongInt(@CopyData));

    그리고 CopyData 메세지 처리 프로그램을 정리해서 첨부 하였으니 수정 하여 보여주세요..

    1. 먼저 CopyData 메세지로 서로 잘 통신하는 걸 보여줍니다.
    2. 다음에 VC++ 제작 DLL 와 통신하며 에러 나는걸 보여줍니다.
    3. CopyData 메세지는 공통이니, VC++ 제작 DLL 의 에러라고 말해줍니다.

    PS: 첨부파일 소스에 BroadcastSystemMessage 등도 있는데, 다 보면 복잡하니, WM_COPYDATA 처리 부분을 중점적으로 보세요..

    PS: 첨부파일은 검증되었습니다.
  • Profile
    aiman 2007.05.19 23:25

    전체적인 내용으로 보면 packet제공 DLL 에서 문제가 있는 듯 합니다.

    60 times 반복 이후 문제가 발생하는 것은 거의 Memory Leak 등의 Resource 문제의 경우 가 가장 많습니다...

    따라서, DLL을 제공해준측에 문의를 먼저 하셔서 문제점을 검토하시는게 문제해결에 도움이 될 것 같네요...

    그럼 즐프하세요...