함수 내에 선언된 지역 변수는 함수가 종료되는 시점에 스택에서 제거된다. ( 이것은 기본 내용 )
그래서 아래와 같이 사용하면 안됨.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | typedef struct tag_PIPE_INFO { WCHAR wcPipeName[256]; }PIPE_INFO; BOOL CPipeServer::StartPipeServer(WCHAR *wcpPipeName ) { DWORD dwThreadID = 0; PIPE_INFO Pipe_Info = { 0, }; StringCchCopy(Pipe_Info.wcPipeName, sizeof(WCHAR)*PIPE_NAME_SIZE, wcpPipeName); OutputDebugString(Pipe_Info.wcPipeName); m_hThread = ::CreateThread( NULL, 0, ConnectPipeThread, (LPVOID) &Pipe_Info, 0, &dwThreadID); if( NULL == m_hThread ) { OutputDebugString(_T("WARNING : StartPipeServer can't create Thread.")); return FALSE; } OutputDebugString(_T("StartPipeServer before Sleep ")); //Sleep(3000); // <<- 주석 OutputDebugString(_T("StartPipeServer return ")); return TRUE; } ULONG __stdcall CPipeServer::ConnectPipeThread(LPVOID lParam) { PIPE_INFO * pPipe_Info = (PIPE_INFO *) lParam; OutputDebugString(_T("CreateNamedPipe PIPE_NAME : %s "), pPipe_Info->wcPipeName); hSvcPipe = CreateNamedPipe( pPipe_Info->wcPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_BUFF_SIZE, PIPE_BUFF_SIZE, NMPWAIT_USE_DEFAULT_WAIT, NULL ); if( hSvcPipe == INVALID_HANDLE_VALUE ) { OutputDebugString(_T("WARNING : CreateNamedPipe Failed! ")); return 0; } ...중략 OutputDebugString(_T("ConnectPipeThread return 1")); return 1; } |
WCHAR Pipe_name[256] = { '\0', };
StringCchPrintf(Pipe_name , 256, _T("\\\\.\\PIPE\\PIPE_NAME"));
StartPipeServer(Pipe_name) ;
이렇게 StartPipeServer 호출 후 디버그 뷰를 확인하면
1) \\\\.\\PIPE\\PIPE_NAME
2) StartPipeServer before Sleep
3) StartPipeServer return
4) CreateNamedPipe PIPE_NAME : ???
5) ConnectPipeThread return 1
이렇게 찍혀있다. 이런 디버그 때문에 Thread 호출부분의 함수가 종료된 후에 Thread 함수가 호출되었기 때문에
( Thread를 생성하는 함수가 종료되면 Thread 함수가 호출되는줄 알았다..)
파라미터로 넘긴 구조체 Pipe_Info가 이미 값이 없어지고 난 후라서 4번째에 PIPE_NAME 값이 제대로 안찍혔다고 생각했다.
근데 StartPipeServer 함수에서 Sleep(3000); 를 주석을 풀고 실행하면, 디버그가 아래처럼 바뀌어있다.
1) \\\\.\\PIPE\\PIPE_NAME
2) StartPipeServer before Sleep
3) CreateNamedPipe PIPE_NAME : \\\\.\\PIPE\\PIPE_NAME
4) ConnectPipeThread return 1
5) StartPipeServer return
============================================================================
결론적으로, CreateThread를 호출해서 Thread를 생성해서 파라미터로 호출한 쪽의 지역변수(구조체)를 넘기면
호출한 쪽의 함수가 종료되기 이전까지 해당 파라미터에 저장된 값은 유효하나
호출한 함수가 종료되버리면 쓰레기 값이 되기 때문에 위와 같은 경우에는 PIPE_INFO 를 동적으로 할당해서 넘겨줘야겠지!
+ 소스 수정해서 테스트했는데 값이 잘 넘어간다.
'Dev Language > C++' 카테고리의 다른 글
C++로 DLL 만들기 (0) | 2017.03.08 |
---|---|
정적 결합과 동적 결합 & 가상함수 (0) | 2016.12.23 |
Is a, Has a 관계 & 상속 (0) | 2016.12.23 |
참조 변수 & 복사 생성자 (1) | 2016.12.06 |
if문과 switch문 (0) | 2016.12.06 |