[완료]extern 변수가 제대로 인식되지 않습니다.

richjaff의 이미지

좀더 구체적으로 설명하자면,
아래의 특정 위치에서만 이상하게 extern 변수의 값이 본체변수의 값과 다르게 0으로 나옵니다.

================ 메인.cpp =========================

/**************************
전역적으로 사용하는 본체 변수
***************************/
HWND hdwnd;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgs, int nCmdShow )
{
MSG msg;
hMainInstance = hInstance;
HACCEL hAccelTable;

hdwnd = CreateDialog(hMainInstance,
MAKEINTRESOURCE(IDD_DIALOG1),
NULL,
(DLGPROC)DialogFunc);
if( !hdwnd ) return FALSE;

ShowWindow( hdwnd, nCmdShow );
UpdateWindow( hdwnd );

hAccelTable = LoadAccelerators(hMainInstance, (LPCTSTR)IDR_ACCELERATOR1);
while( GetMessage(&msg, NULL, 0, 0) )
{
if (IsDialogMessage(hdwnd, &msg)) continue;
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}

// 문제가 일어나는 부분 : 스위치블럭에서 "case WM_INITDIALOG: 구간"
BOOL CALLBACK DialogFunc(HWND hdwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
INITCOMMONCONTROLSEX InitCtrlEx;

InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
InitCommonControlsEx(&InitCtrlEx);

switch(Msg)
{
// 문제가 일어나는 구간 - 아래에 문제가 일어나는 지점을 표시해뒀습니다.
case WM_INITDIALOG:
{
// Load Icons
hLargeIcon = LoadIcon ( hMainInstance, MAKEINTRESOURCE(IDI_LINLARGE) );
hSmallIcon = (HICON) LoadImage ( hMainInstance, MAKEINTRESOURCE(IDI_LINSMALL), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR );
SendMessage ( hdwnd, WM_SETICON, ICON_BIG, (LPARAM)hLargeIcon );
SendMessage ( hdwnd, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon );

// status bar init
hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
hdwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);

//modify system menu
//(remove Restore, Maximize and Resize)
HMENU hSysMenu=GetSystemMenu(hdwnd, FALSE);
DeleteMenu(hSysMenu, 0, MF_BYPOSITION);
DeleteMenu(hSysMenu, 1, MF_BYPOSITION);
DeleteMenu(hSysMenu, 2, MF_BYPOSITION);
//store main window handle

// message handling tru dialog
hAppTime=GetDlgItem(hdwnd, IDC_APPTIMER);
hData=GetDlgItem(hdwnd, IDC_LIST);
hchatlog = GetDlgItem(hdwnd,IDC_LIST2);
hKick=GetDlgItem(hdwnd, IDC_KICKUSER);
hBan=GetDlgItem(hdwnd, IDC_BANUSER);
hLoginServer=GetDlgItem(hdwnd, IDC_LOGINSERVERSTATUS);
hDBServer=GetDlgItem(hdwnd, IDC_DBSERVERSTATUS);
hDBAutoCreateAccounts=GetDlgItem(hdwnd, IDC_DBAutoCreateAccounts);
hDBExprate =GetDlgItem(hdwnd ,IDC_DBExprate);
hDBDroprate = GetDlgItem(hdwnd , IDC_DBDroprate);
// status bar size
hStatus = GetDlgItem(hdwnd, IDC_MAIN_STATUS);

SendMessage(hStatus, WM_SIZE, 0, 0);

// status bar messages
int statwidths[] = {165, -1};
SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);

/****************************************************
문제의 지점입니다.
*****************************************************/
// 이렇게 직접적으로 변수를 넘겨주면 출력이 잘 됩니다.
SendDlgItemMessage(hdwnd, IDC_LIST, LB_ADDSTRING, 1, (LPARAM)(LPSTR)"문자열출력");

// 하지만 이렇게 할경우 hdwnd값이 0으로 떠서 출력이 안됩니다.
// ======== 문제의파일.cpp 부분 요약 ============
// extern HWND hdwnd;
//
// void Function(char* str)
// {
// DWORD PtrAddress = hdwnd를 DWORD로 reinterpret_cast를 통해 캐스팅해서 입력;
// PrintOut(PtrAddress); // 경고 메세지 박스로 핸들 값 출력하는 부분입니다.
// 넘겨받은 str을 extern으로 선언되어진 hdwnd 핸들을 통해 출력함.
// SendDlgItemMessage(hdwnd, IDC_LIST, LB_ADDSTRING, 1, (LPARAM)(LPSTR)str); }
// }
// =============================================
// 이렇게 정의된 상태에서 위의 함수를 실행해보면
Function("출력아 되어라");

// 결과는 핸들값은 0으로 뜨고, 메세지는 당연히 출력이 안되어집니다.
// 즉, 전자에서는 전역변수 HANDLE hdwnd 값을 직접 넘겨주면, 출력이 잘되지만,
// 그 다음에 호출해본 Function 함수에서는 extern HANDLE hdwnd 값이 0으로 인식되어 출력이 안되는 문제입니다.
// 더 이해하기 힘든 점은 이 현상이 현위치 "다이얼로그 초기화 부분인 case WM_INITDIALOG:"지점에서만 일어나고,
// 다이얼로그가 초기화 되고 난뒤, 메세지 버튼을 눌러서 아래의 구간"case IDC_MSGBUTTON:"에서 실행시켜보면
// extern HANDLE hdwnd 값이 정상적으로 인식되어진다는 겁니다.

return TRUE;
}

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_MSGBUTTON: // 여기서는 외부 정의된 함수내에서도 extern HANDLE hdwnd가 잘 인식됩니다.
{
// extern HANDLE hdwnd 값또한 정상적으로 출력되구요
Function("출력이 잘 되어진다!");
}
break;
}
break;
case WM_DESTROY:

PostQuitMessage(0);
return TRUE;
}
return FALSE;
}

물론 위의 문제를 다른 방법으로 해결할 수 있긴 하지만,
위의 문제를 일으키는 원리를 모르고 넘어가면 나중에 코딩하면서 문제가 될것 같습니다.
이 부분에 대해서 이유를 좀 알려주세요. 부탁드립니다!

richjaff의 이미지

HANDLE hdwnd; 가 아니라
HWND hdwnd; 였네요...
=========================
다시 수정합니다.

글로 쓰느라 HANDLE로 잘못 썼었는데,
이미 소스에서는 HWND로 쓰고, extern으로 선언한 변수가 컴파일시
에러 없이 빌드됨에도 불구하고 위의 현상이 생깁니다.
도움좀 부탁드립니다.

=========================
다시 수정합니다.;;

소스를 보니 문제를 이해했습니다.
// 여기서 사용되어지는 핸들은 전역변수 HWND hdwnd이지만
hdwnd = CreateDialog(hMainInstance,
MAKEINTRESOURCE(IDD_DIALOG1),
NULL,
(DLGPROC)DialogFunc);

// 여기서 넘어오는 변수는 매개변수더군요.
BOOL CALLBACK DialogFunc(HWND hdwnd, UINT Msg, WPARAM wParam, LPARAM lParam)

결국에는 해결 했습니다... 쓸데없는 글 읽어주셔서 감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.