2010년 5월 31일 월요일

_CtrlsValidHeapPointer(pUserData) Debug Assertion 해결법

대부분의 경우 메모리 문제때문에 생긴다. 메모리 할당과 해제에 문제가 없는지 확인한다.
다른 문제가 없다면 debug와 release용 DLL 혹은 LIB를 섞어쓴 것을 의심해야 한다. 특히 VS2008은 debug와 release를 명확히 구분하므로 섞어쓴 경우  _CtrlsValidHeapPointer(pUserData) debug assertion을 표시한다.

2010년 5월 30일 일요일

다국어 지원 위해 반드시 Unicode 사용

VS2008을 쓰니 이제 개발도 유니코드(Unicode)로 해야겠다. Unicode(wide character: wchar_t) 체계에서는 모든 문자(영어 혹은 한글)는 2 bytes라는 것만 기억하면 되겠다.

[유니코드 선언과 사용]
1. 문자변수 선언: TCHAR

2. 문자열변수 선언: LPCTSTR, LPTSTR, TCHAR *

3. 문자열 정의: _T("...")

4. 문자열 함수: _tcs...()
   - _tcslen: 문자열의 요소갯수를 반환. ANSI인지 Unicode인지 구별하지 않고 사용한 문자열의 요소갯수(byte수가 아님)를 알려줌.
   - 요수갯수는 문자열을 구성하는 요소들(char, TCHAR, or wchar_t)이 몇 개인가이고 byte수는 문자열이 차지하는 실제 메모리 공간의 수를 뜻함.
   - sizeof(TCHAR):  문자의 byte수를 알려줌. ANSI이면 1 byte, Unicode이면 2 bytes.
   - strlen: 문자열의 byte수를 반환함.

5. MBCS(Multi-Byte Character Set)와 Unicode의 변환
   - MBCS to Unicode: mbstowcs(...) or MultiByteToWideChar(...)
   - Unicode to MBCS: wcstombs(...) or WideCharToMultiByte(...)
   - USES_CONVERSION 선언후 A2W(...) or W2A(...) 사용

[유니코드 함수]
1. 유니코드를 지원하지 않는 함수: 이 함수 입력은 반드시 ASCII가 되어야 함, _T("...")로 정의하면 안 됨
   - GetProcAddress()

[참고문헌]

VS2008은 Class Wizard가 없구나.

예전 VS2003부터 없어졌단다. VS2008에서 class wizard없이 message map을 다루는 방법은 첨부링크에 있다. 쉽게 말하면, message map을 연결하기 원하는 클래스로 가서 마우스의 오른쪽을 클릭한 후 "속성" 항목을 누른다. 그러면 "속성창"이 떠서 이 창에 입력하면 된다. "속성창"은 항목별로 구분되어 있다.
  • "속성창 -> 속성"은 클래스 속성 자체를 변경할 수 있다.
  • "속성창 -> 메시지"에는 해당 클래스에 Windows message map을 연결할 수 있는 기능이 있다.
  • "속성창 -> 이벤트"는 클래스 바깥에서 발생한 이벤트(event)를 잡는 COMMAND나 UPDATE_COMMAND_UI 함수를 설정할 수 있다.
  • "속성창 -> 재정의"에서는 현재 클래스의 부모 클래스 기능을 재정의할 수 있다.

class member variable을 추가하려면 "클래스 뷰"로 가서 마우스의 오른쪽 클릭후 "추가 -> 변수 추가"를 누르면 된다.
class wizard를 다시 보고 싶으면 VS2010을 사용해야 한다. MS도 class wizard의 중요성을 다시 인식한 것인지 VS2010부터는 다시 부활했다.

2010년 5월 28일 금요일

#pragma omp for 사용시 주의점

OpenMP(Open Multi-processing)는 사용이 매우 쉬우나 프로그램 작성시 아래를 주의해야 한다.

1. for 내부에 사용하는 함수는 OpenMP-safe function이 되어야 한다.
   - 내부 사용함수가 global variable 등을 공유해서 사용하면 다른 결과를 낼 수 있으므로 절대 global variable에 연관된 함수를 쓰면 안됨

2. for 내부에 사용할 수 없는 연산자가 있다.
   - +=, -=, *=, /= 등과 같은 축적연산자가 for index와 연관된 경우 실행순서에 따라 다른 값이 출력될 수 있음 -> 절대 사용하면 안됨
   - 굳이 for index와 관계된 축적연산자를 사용하려면 reduction을 사용해서 #pragma omp for reduction(...)을 구성해야 함

2010년 5월 24일 월요일

VS2008에서 Non-static Member Function Pointer 쓰는 방법

첨부링크에 자세하게 설명되어 있다. FAQ 형태의 설명은 아래링크를 참고할 수 있다.
class Adder
{
    public:
    int Add(int x, int y) const
    {
        return x + y;
    }
};
Adder adder;
typedef int (Adder::*MemberFunctionPointerType)(int x, int y) const;
MemberFunctionPointerType mfp = &Adder::Add;
int result = (adder.*mfp)(4, 5);

DLL로 인한 R6034 Runtime Error

1. 여러 DLL을 쓰다보면 VS2008에서 R6034 runtime error가 생기기도 한다.
자세한 설명은 위의 첨부링크에 있다. 이때는 문제를 일으키는 DLL 링크시 "msvcrt.lib"를 제거하도록 하자. 속성 -> 구성 속성 -> 링커 -> 입력 -> 특정 라이브러리 무시에 "msvcrt.lib"를 집어 넣으면 된다. 물론 "msvcrt.lib"를 제거해서 link error가 발생하면 원래대로 돌리고 다른 방법을 찾아야 한다.

2. 혹은, DLL을 manifest를 사용하지 않고 읽어들인 경우 발생할 수 있다.
이에 대한 해결책은 http://www.codeproject.com/kb/cpp/vcredists_x86.aspx에 있다.

3. VS98을 VS2008로 변환해서 생긴 문제라면 귀찮은 과정을 반복해야 한다.

- VS98과 동일한 project name으로 VS2008 project를 만든다.
- 다음으로 VS98에 있는 모든 헤더(header)와 소스(source) 파일을 VS2008로 옮긴다.
- VS2008에서 옮긴 헤더(header)와 소스(source) 파일을 등록한다.
- 다음에는 리소스(resource)를 옮겨야 한다. VS98의 resource folder인 "res"를 VS2008로 이동한다.
- VS98 project를 VS2008로 변환할 때 생긴 *.rc, *.aps 파일을 새롭게 만든 VS2008 project에 덮어쓴다. 당연히 resource.h도 가져와야 한다.

VS2008에서 LNK2019 해결방법

링커에러는 일반적으로 해결이 힘들다. 첨부링크를 따라가서 하나하나 확인해 보자.


2. template class 안에서는 friend 선언을 사용하지 말자.
어떤 경우 LNK2019가 발생한다. 이 경우, 그냥 friend 선언을 삭제하면 된다.

2010년 5월 22일 토요일

VS98에서 VS2008로 변환시 Compiler Error 대처법

   - <iostream>, <fstream> 으로 변경
   - using namespace std 선언

2. ios::nocreate
   - ios::_Nocreate으로 변경
   혹은
   - ios_base::in으로 변경(입력으로 열기로 단순 설정)

3. istream::eatwhite
   - skipws를 사용
   - 하지만 파일끝에 EOF(End of File)이 있으면 assertion이 생기니 실행전에 EOF 여부를 반드시 확인해야 함
[예제]
ifstream file("data.txt");
file >> skipws;

4. 현재 코드 페이지에 표시할 수 없는 문자
   - #pragma warning(disable:4819) 사용

5. char *는 LPTSTR로 변경

6. LPTSTR에서 char *로 변환 불가시
   - 프로젝트 속성에 가서 구성 속성 -> 일반 -> 문자 집합을 '멀티바이트 문자 집합 사용'을 선택

VS98 사용자가 VS2008로 전환하는 법

다음 링크에 삼성전자에서 만든 "Visual Studio 2008로 가는 길"이라는 좋은 자료가 있다.

VS2008 or VS2010에서 속도 최적화 방법

Debug에서는 최적화를 설정하면 안된다.

1. 속성 > 구성 속성 > 일반에서 옵션 설정
   - 전체 프로그램 최적화: 링크 타임 코드 생성 사용

2. 속성 > 구성 속성 > C/C++ > 최적화에서 옵션 설정
   - 최적화: 속도 최대화
   - 인라인 함수 확장: 적합한 것 모두 확장
   - 내장 함수 사용: 예
   - 크기 또는 속도: 코드 속도 우선
   - 프레임 포인터 생략: 예
   - 파이버 안전 최적화 사용: 아니오
   - 전체 프로그램 최적화: 예

3. 속성 > 구성 속성 > 링커 > 최적화에서 옵션 설정
   - 링크 타임 코드 생성: 링크 타임 코드 생성 사용
   - 참조: 참조하지 않는 데이터 제거 (VS2010: 예)
   - COMDAT 정리 사용: 중복 COMDAT 제거 (VS2010: 예)

2010년 5월 20일 목요일

VS2008에서 OpenMP 사용

병렬 프로그래밍을 하려면 어쩔 수 없이 VS2008을 써야 하는구나.

아래는 참고링크:
- http://www.openmp.org (모든 자료 존재)
- http://himskim.egloos.com/3261640 (쉬운 한글 설명)

아래는 MSDN에서 찾은 설정방법:
Visual Studio 개발 환경에서 이 컴파일러 옵션을 설정하려면 프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 방법: 프로젝트 속성 페이지 열기를 참조하십시오.

1. 구성 속성 노드를 확장합니다.
2. C/C++ 노드를 확장합니다.
3. 언어 속성 페이지를 클릭합니다.
4. OpenMP 지원 속성을 수정합니다.