프로그래밍 12

goto 대신에 do { ... } while (false)를 사용한 에러처리

C/C++ 코딩을 하다보면 흔히 아래와 같은 에러처리 코드를 만나게 된다. ... if (!condition1) goto cleanup; ... if (!condition2) goto cleanup; ... if (!condition3) goto cleanup; ... if (!condition4) goto cleanup; ... cleanup: // 메모리 해제등의 정리 작업 고급 언어에서는 goto를 사용하지 말라고 많이 하고 실제 goto의 사용이 스파게티 코드를 만드는 경우가 많기 때문에 사용하지 않는 것이 좋지만 C/C++에서는 finally를 지원하지 않기 때문에 위와 같은 코드는 묵인해주는 경우가 많다. 그래도 goto를 피하고 싶기 때문에 아래처럼 하기도 한다. ... if (!condit..

개발 2010.03.25

Visual C++ 2005 CRT DLL 버전 충돌 문제

VS2005 CRT DLL(msvcp80.dll, msvcr80.dll)을 사용하는 COM 모듈을 개발할 때 설치 대상 PC에 .NET 2.0 SP1이나 .NET 3.0 SP1이 설치되어 있는 경우 COM 등록 시에 로드하는 CRT DLL 버전 8.0.50727.762를 side by side assemblies 기능에서 자동으로 8.0.50727.1433으로 리다이렉트해준다. 문제는 1433 버전으로 작동하는 경우 COM 등록이 안 되는 등의 에러가 발생한다. Isolated COM이나 Per-application Configuration(Windows XP, Windows Vista)으로도 해결할 수 있지만 가장 간단한 방법은 Private Assemblies로 항상 762 버전을 사용하도록 하는 것..

개발 2008.09.30

크리티컬 섹션을 이용한 스레드 동기화

다중 스레드 환경의 프로그램에서 여러 스레드 사이에서 공유하는 리소스를 사용한다면 반드시 스레드 간 동기화를 해줘야 한다. Windows 환경이라면 스레드 동기화를 위해서 가장 많이 사용하는 동기화 방법은 크리티컬 섹션일 것이다. // 크리티컬 섹션 변수 CRITICAL_SECTION cs; // 크리티컬 섹션 초기화 InitializeCriticalSection(&cs); // 공유 리소스를 사용하는 스레드 사용 ... // 모든 스레드가 종료된 후 크리티컬 섹션 삭제 DeleteCriticalSection(&cs) DWORD WINAPI ThreadProc(LPVOID pParam) { ... // 크리티컬 섹션 소유권 가져오기 EnterCriticalSection(&cs); // 공유 리소스에 접근..

개발 2007.12.18

VC6의 CHtmlView 버그

VC6의 CHtmlView에는 버그가 있어서 텍스트 입력에서 Tab, Del, Enter 키등이 동작하지 않는다. VC7이상의 CHtmlView에서는 버그가 수정되었는데 PreTranslateMessage()를 오버라이딩함으로 해결하였다. VC6에서 해당 버그를 수정하려면 CHtmlView를 상속해서 VC7의 CHtmlView::PreTranslateMessage()로 PreTranslateMessage()를 오버라이딩하면 된다. BOOL CHtmlView::PreTranslateMessage(MSG* pMsg) { ASSERT(pMsg != NULL); ASSERT_VALID(this); ASSERT(m_hWnd != NULL); // allow tooltip messages to be filtered..

개발 2007.09.05

Visual C++로 XPCOM 컴포넌트 만드는 방법

모질라 파이어폭스에서 사용하기 위한 XPCOM 컴포넌트를 만들기 위해서 Visual C++를 사용할 수 있는 방법에 대한 설명입니다. 일반적으로 XPCOM을 만드는 경우 GCC를 많이 사용하겠지만 Windows 환경이라면 역시 Visual C++을 이용해서 XPCOM을 만들 수 있다면 더 편리할 것입니다. 모질라 개발자 사이트에 있는 내용을 참고하였고 XPCOM 개발에 대한 기본적인 지식이 있는 것으로 전제합니다. XPCOM에 대한 자세한 내용은 Mozilla Developer Center를 참고하시기 바랍니다. 개발 환경 설정 먼저 Visual C++이 설치되어 있어야 합니다. Microsoft에서 무료로 배포하는 Visual C++ Express를 사용할 수도 있습니다. 여기서는 Visual C++ ..

개발 2007.07.19

COM 인터페이스 포인터를 서로 다른 Apartment로 전달하기

멀티쓰레드 환경에서 COM을 사용할 때 서로 다른 쓰레드 간에 인터페이스 포인터를 넘겨서 사용하는 경우가 있을 수 있습니다. 이 때 Apartment Threaded인 경우 문제가 생깁니다. 서로 다른 Apartment로 인터페이스 포인터를 넘겨야 하는데 문제가 발생하는 경우가 있습니다. 이런 경우 Global Interface Table(GIT)을 사용하면 됩니다. 다음은 MS 기술자료(http://support.microsoft.com/kb/601770/ko)에 나와 있는 GIT 사용 단계입니다. 1. GIT 인스턴스를 생성합니다. IGlobalInterfaceTable *pGIT = NULL; ::CoCreateInstance (CLSID_StdGlobalInterfaceTable, NULL, CL..

개발 2007.06.27

Windows NT 계열에서 프로세스 강제 종료하기

Windows에서 프로세스를 강제 종료하려면 TerminateProcess() API를 사용하면 된다. 그런데 Windows NT 계열에서 TerminateProcess()를 사용하려면 PROCESS_TERMINATE 접근 권한을 가지는 프로세스 핸들이 필요하다. OpenProcess()로 PROCESS_TERMINATE 접근 권한의 프로세스 핸들을 얻을 수 있는데 High integrity level 이상의 프로세스는 그 전에 먼저 SeDebugPrivilege 권한을 획득해야 한다. 따라서 프로세스를 종료하기 위한 절차는 다음과 같다. 1. 현재 프로세스의 권한을 변경하기 위한 액세스 토큰의 핸들을 가져온다. OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_..

개발 2007.06.01

투명 이미지 그리기(MaskBlt, TransparentBlt)

부분적으로 투명한 이미지는 상당히 쓸모가 많다. 특히 스킨 형태의 어플리케이션을 개발하려면 투명 이미지를 그리는 것은 꼭 필요한 요소 중 하나다. WIN32에서도 MaskBlt(), TransparentBlt() 등의 투명한 이미지를 그리기 위한 API를 제공하지만 MaskBlt()는 Windows NT 계열에서만 사용할 수 있고 TransparentBlt()는 Windows 98이나 2000이상에서만 사용이 가능하다. 만약 Windows 9X나 Windows 2000 미만에서 투명한 이미지를 그리려면 다음과 같은 방법으로도 가능하다. 최근에는 Windows 9X 사용자가 줄어서 거의 필요 없지만 말이다. 1. 먼저 배경색을 이용해서 마스크 비트맵을 만든다. 이미 마스크 비트맵이 있다면 생략이 가능하다...

개발 2007.04.03

메모리 DC를 이용한 더블 버퍼링

화면에 이미지나 도형, 텍스트 등 여러가지를 출력하다 보면 깜박거리는 현상을 보게 된다. 한 번 출력하고 말 것이라면 크게 문제가 안 될 수 있지만 지속적으로 출력하는 상황에서는 깜박거림은 피하고 싶은 문제 중 하나이고 가장 쉽고 일반적인 해결책은 더블 버퍼링이다. 다음은 메모리 DC를 이용한 더블 버퍼링 방법이다. 1. 출력하려는 크기의 비트맵과 메모리 DC를 생성하고 메모리 DC에 생성된 비트맵을 선택한다. HBITMAP hbmMem = CreateCompatibleBitmap(hdc, 48, 48); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem); 2. 생성한 메모리 DC(hdcM..

개발 2007.03.31