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. 모두 모두 하시는 일 잘 되시기를.... 많이 많이 도움을 주십시요.
흠.. 보내는 쪽의 에러로 보입니다..
한가지 생각나는게 있네요..
아래가 제가 예전에 썼던 것인데... 보시면 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: 첨부파일은 검증되었습니다.