태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

[VisualStudio] 비주얼 스튜디오 C++ 에러 검출하기 (GetLastError)

Posted on 2008.03.01 22:23
Filed Under Development

  • 이 글은 jake 에 의해 www.jakeworld.net 에서 작성되었습니다.

  • 퍼가실 때는 이 박스와 함께 복사해주세요.

사용자 삽입 이미지

많은 분들이 알고 계실진 모르겠지만 , 비주얼 스튜디오에는 모든 에러를 검출 할 수 있는 API를 제공합니다.

 (참고로 저는 최근에 알았네요 ^^;)

바로 GetLastError() 함수인데 소켓 프로그래밍 할때는 거의 필수적으로 쓰인다고 하니 알아두시면 좋을듯 하네요.

함수명 처럼 마지막에 발생한 에러를 체크하게 되는데 딱 봐도 로직 에러에 많이 쓰일 법 하지요? ^^


다음은 GetLastError의 MDSN 원문입니다.

GetLastError Function

Retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.

Visual Basic:  Applications should call err.LastDllError instead of GetLastError.
DWORD WINAPI GetLastError(void);

Parameters

This function has no parameters.

Return Value

The return value is the calling thread's last-error code.

The Return Value section of the documentation for each function that sets the last-error code notes the conditions under which the function sets the last-error code. Most functions that set the thread's last-error code set it when they fail. However, some functions also set the last-error code when they succeed. If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not.

Windows Me/98/95: Functions that are actually implemented in 16-bit code do not set the last-error code. You should ignore the last-error code when you call these functions. They include window management functions, GDI functions, and Multimedia functions. For functions that do set the last-error code, you should not rely on GetLastError returning the same value as it does under other versions of Windows.

Remarks

Functions executed by the calling thread set this value by calling the SetLastError function. You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function.

To obtain an error string for system error codes, use the FormatMessage function. For a complete list of error codes provided by the operating system, see System Error Codes.

The error codes returned by a function are not part of the Windows API specification and can vary by operating system or device driver. For this reason, we cannot provide the complete list of error codes that can be returned by each function. There are also many functions whose documentation does not include even a partial list of error codes that can be returned.

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no system error code has this bit set. If you are defining an error code for your application, set this bit to one. That indicates that the error code has been defined by an application, and ensures that your error code does not conflict with any error codes defined by the system.

To convert a system error into an HRESULT value, use the HRESULT_FROM_WIN32 macro.

Example Code

For an example, see Retrieving the Last-Error Code.

Requirements

Client

Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Server

Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.

Header

Declared in Winbase.h; include Windows.h.

Library

Use Kernel32.lib.

DLL

Requires Kernel32.dll.




간단한 예를 보여드리겠습니다.

다음 코드는 제가 2005에서 작업한 소스코드의 일부분인데 VS2008로 넘어오면서 문제점이 생기더군요.


CFileDialog fd(TRUE,"bmp",FileName); 
if(fd.DoModal() != IDOK) return; 
FileName=fd.GetFileName(); 
CFile f; 
f.Open(FileName,CFile::modeRead);

파일 열기 다이얼로그에서 선택된 파일의 이름을 가지고 와서 그것을 여는 부분인데

여태까지 아무 생각 없이 잘 되서 쓰다가 VS2008에서 뜬금없이 파일을 열지 못하는 문제가 발생했었습니다.

의심나는 부분이 있군요. 저기 f.Open 부분이요.

이럴때 사용하는게 처음에 언급한 GetLastError() 함수입니다.

위 코드에 적용시켜 보겠습니다.

CFileDialog fd(TRUE,"bmp",FileName); 
if(fd.DoModal() != IDOK) return; 
FileName=fd.GetFileName(); 
CFile f; 
f.Open(FileName,CFile::modeRead); DWORD ErrorValue= GetLastError();
마지막 라인을 주시하세요.

f.Open 부분에서 문제가 생겼을 거라는 가정하에 바로 아래에 마지막에 발생한 에러값을 가져오도록 지시했습니다.

이 DWORD 타입의 ErrorValue 변수값에는 마지막에 발생한 에러타입의 번호가 대입됩니다.

브레이크포인터를 걸든지 메세지 박스로 출력하든지 대입된 시점의 에러코드를 알아냅니다.

제 경우는 2번이 나왔더군요.

그럼 VS 메뉴줄에 도구->오류조회를 찾아들어갑니다.

값 항목에는 방금 전 얻어낸 에러코드를 입력하고 찾기를 누르세요.

그럼 아래 오류메세지 항목에 어떤 에러인지 나옵니다.

저는 "지정된 파일을 찾을 수 없습니다. " 가 나왔네요.

즉, 2번 에러코드는 지정된 파일을 찾지 못한 경우... 그러니까 f.Open 에서 동작이 수행되지 않았던거죠. ^^



사실 f.Open을  if로 둘러싸고 부울테스트를 하는게 정석입니다.

코드상은 간략화 하기 위해 바꿨지만 실제론 그렇게 해서 FALSE 를 리턴하는걸 확인하고 파일을 못열겠구나 하고 생각하고 있었지요.


이유는 오픈할 때 FileName에는 파일명만 들어있지 경로가 없기 때문이죠.

상식적으로는 에러가 나는게 정상이 맞는데 VS2005에서는 이상하게 잘 열리더군요.


파일 오픈 경우 FALSE 리턴은 거의 파일을 못열거나 실패했다고 확신 할 수 있지만 여러가지 상황이 존재하는 경우라면?

하나하나 테스트 하기엔 시간이 너무 아깝습니다.

"나는 하나하나 테스트 해 가는게 삶의 낙이다" 라고 하시는 분들에겐 굳이 말리진 않겠습니다. ㅡㅡ;


어쨋든 저런 상황이라면 조금 곤란한 문제점이 생깁니다.


참고로 저 에러는 FileName=fd.GetPathName(); 으로 해결했습니다.

경로와 파일이름을 포함한 풀패스(Full-path)를 가져오는 메소드죠. ^^

이 글은 스프링노트에서 작성되었습니다.

신고

댓글을 달아 주세요

  1. 이상우 2009.12.11 17:06 신고  댓글주소  수정/삭제  댓글쓰기

    와, 이거 정말 특이합니다.
    저도 VS2005에서 잘 열리던 파일이 VS2008로 바꾸고 나서 안열리기에
    이곳 저곳 찾아 보았는데, 이 글 보고 해결 봤습니다.

    VS2005에서는 분명히 파일 이름만으로도 파일이 열리는데, VS2008에서는 풀패스를 넣어줘야 열리네요. 이거 왜 그럴까요? 혹시 왜 그런지도 알아내셨나요?

    감사합니다. ^^

    혹시 알아내셨으면 klassesw@mail.hongik.ac.kr 요기로 내용 좀 알려 주시면
    감사하겠습니다. ^^

    • JakeWorld 2009.12.21 14:55 신고  댓글주소  수정/삭제

      그런가요 ^^;
      사실 풀패스가 메소드 의미로 볼땐 맞는것 같은데, 여태까지 그냥 파일명도 잘 되니 사용했던게 아닐까요.
      정상적이라고 보는 정도에서 저는 더이상 찾아보진 않았습니다. ㅎㅎ

About



모바일 페이지 QR 코드

Counter

· Total
: 468,975
· Today
: 83
· Yesterday
: 130


DNS server, DNS service