블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2324)
Unity3D (568)
Programming (472)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (34)
3DS Max (3)
Game (12)
Utility (116)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (38)
Android (13)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (19)
Interest (37)
Thinking (36)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (2)
냥이 (9)
육아 (9)
Total1,344,974
Today78
Yesterday321
Statistics Graph

달력

« » 2019.12
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        

공지사항

태그목록


TLS - Thread Local Storage [ 펌 http://purewell.egloos.com/3398289]
쓰레드를 돌리다보면 해당 쓰레드에서만 유효한 변수를 만들고 싶을 때가 있다. 그럴 때 어떻게 해야할까? 쓰레드 개수만큼 벡터를 잡고, 해당 쓰레드마다 벡터 인덱스를 넘겨주는 것도 나름 방법이지만, 이러한 경우를 위해 TLS라는 것이 존재한다. 축약처럼 쓰레드 안에서만 따로 스토리지를 할당한 것인데, 일반 프로세스의 스텍과 비슷하나 그 크기는 프로세스 것보다 당연히 작고 제약이 심한 편이다. 뭐 암튼 그런게 있다고 치자.

* GCC 메뉴얼 보면 TLS가 아니라 TSD(Thread Storage Duration)이라고 표현하였는데 대충 같은 말이다.

이것을 위해 POSIX는 pthread_key_create, pthread_get/setspecific 등 함수를 마련해놨지만 눈만 팽글팽글 돌고, 소스만 지저분해져 보일 것 같다. 귀찮으면 C99, C++98 표준 __thread 키워드를 사용하자. MSDN에 보니 __thread가 없어 보인다. 이가 없으면 잇몸으로라도...
#define __thread __declspec( thread )
대충 이 정도면 될 듯하다. 자자 각설하고, __thread란 키워드는 TLS에 변수를 선언해주는 일을 한다. 위에 나열한 pthread_* 함수를 호출하는 것으로 컴파일러가 대신 해석해주는 것일 수도 있으나 이건 가정이므로 넘어가고. 사용에 주의해야할 점은 아래와 같다. (대충대충 표준하고 MSDN 보면서 정리한 것임)
  1. 글로벌 변수나 static 변수에만 사용 가능하다.
    - function 안에 local 변수가 static이 아니라면 뭐더게 TLS에 저장할까? 당연히 그럴 필요가 없기 때문에 저런 제약이 있는 것이다. 이는 class에서 멤버 변수에도 적용한 법칙이다. static으로 선언한 멤버 변수에만 저 키워드를 사용할 수 있다.
  2. SO(DLL)과 로컬 영역을 넘나들면 뻑난다.
    - ... 그러니까 쓰지마라. 왜?
  3. 타입에 대한 한정자로 사용이 불가능하다.
    - const처럼 쓰지 말라는 것이고, 무조건 타입 앞에 붙이란 말이다. (VC에만 해당)
  4. 객체 이름과 이름 없는 객체에만 쓸 수 있다.
  5. 앞에 붙을 수 있는 건 static과 extern 뿐이다.
  6. 클래스 자체를 TLS에 넣을 때는 생성자와 소멸자가 없어야 한다.
역시나 예가 없으면 아무 것도 할 수 없는 나를 위하여~*
#include <iostream>
using namespace std;

__thread int gTest1;      // 성공

__thread void func(void); // 실패

void
func(__thread int lTest2) // 실패
{
}

class A
{
    static __thread int mTest3;   // 성공
    __thread int mTest4;          // 실패
};

int
func(void)
{
    static __thread int lTest5; // 성공
    __thread int lTest6;   // 실패
}

__thread union
{
    int i;
    char p[sizeof(int)];
} gTest7;   // 성공

__thread struct
{
    int i;
    char p[sizeof(int)];
} gTest8;   // 성공

class MyClass
{
public:
    int i;
    MyClass() i(0) {}
};

__thread MyClass cTest9; // 실패

int __thread * gTest9; // gcc 성공

int
main(int,char**)
{
    return 0;
}
나머진 시간 나는대로 정리하도록 해야겠다.


출처 : http://blog.naver.com/kkan22?Redirect=Log&logNo=80057856857

'Programming > C/C++' 카테고리의 다른 글

GameLoop (번역)  (0) 2010.09.16
IME 관련  (0) 2010.09.10
TLS (Thread Local Strorage)  (0) 2010.08.30
TCHAR을쓰면 바뀌는 함수들  (0) 2010.07.27
TCHAR printf  (0) 2010.07.12
A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
Posted by blueasa
TAG tls

댓글을 달아 주세요


sprintf -> _stprintf
atoi -> _tstoi
strlen -> _tcslen
strcpy -> _tcscpy
fprintf -> _ftprintf
strcmp -> _tcscmp

strcpy -> _tcscat

char* 을 TCHAR* 로 변환은 (TCHAR*)_bstr_t(<char*형>);

'Programming > C/C++' 카테고리의 다른 글

IME 관련  (0) 2010.09.10
TLS (Thread Local Strorage)  (0) 2010.08.30
TCHAR을쓰면 바뀌는 함수들  (0) 2010.07.27
TCHAR printf  (0) 2010.07.12
A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
Posted by blueasa
TAG TCHAR

댓글을 달아 주세요

TCHAR printf

Programming/C/C++ / 2010. 7. 12. 13:59
#include<windows.h> //TEXT()
#include<tchar.h> //TCHAR, _stprintf(), _tprintf()

TCHAR test[32];

_stprintf(test, TEXT("%f"), 0.01f); //_UNICODE가 선언되면 swprintf(), _MBCS선언되면 sprintf()
_tprintf(TEXT("%s\n"), test); //_UNICODE가 선언되면 printf(), _MBCS선언되면 printf()

입니다, TCHAR, _stprintf(), _tprintf() 전부 메크로죠, _UNICODE나 _MBCS가 선언되면, 어느게 선언되있는 가에 따라서 자동으로 선택해줌니다, TCHAR는 _UNICODE가 선언되면 wchar_t고, _MBCS선언되면 char입니다.

http://msdn.microsoft.com/en-au/library/tsbaswba.aspx


출처 : http://www.winapi.co.kr/ApiBoard/content.php?pk=54186&table=tblqa

'Programming > C/C++' 카테고리의 다른 글

TLS (Thread Local Strorage)  (0) 2010.08.30
TCHAR을쓰면 바뀌는 함수들  (0) 2010.07.27
TCHAR printf  (0) 2010.07.12
A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
Posted by blueasa

댓글을 달아 주세요


오늘 갑자스럽게  아는 동생이 물어본것이 있었다..

상속 관계에서 클래스 객체 선언방식의 차이점이 었다.

즉,

  A * pA = new B;
  B * pB = new B;

이 두개의 차이점

 

쉽게 이야기해서 접근시작점의 차이인데.. 초반에 버벅거리다니...

아직 내공 부족인가 보다.

 

아무튼 기억을 더듬어서 대답해주고 확인겸 프로그래밍해보고

 

다시 잊어버리지 말라구 기록에 남긴다.

 

위의 차이점은 간단히 말해

  A * pA = new B;

부모 클래스의 virtual 함수에 의한 오버라이딩을 위해 쓴다고 말하면 될것 같다.

예를 들어 A클래스에 virtual void A1()이라는 함수가 있고 B클래스에 void A1()이라는 함수가 있다면

pA->A1()는  당연히 B 클래스의 A1()이 호출된다.

만약 B 클래스의 A1()이 없다면 A 클래스의 A1() 호출된다.

그런데 B클래스에 A1()있고 A 클래스에도 A1()있는데 A클래스의 virtual 키워드가 붙지 않았다면

A클래스의 A1()이 B 클래스를 무시하고 실행되어 버린다. 왜? A부모우선이니.

그런데   B * pB = new B; 에서는 B클래스의 A1()이 실행된다.

말그대로 B 클래스 우선이 된다. 

 

아래는 대략적인 예제 남긴다.

내공를 쌓도록 공부하면 잊지 말도록 하자 정말로....

 

#include <iostream>
#include <stdio.h>
using namespace std;

class A
{
public:
 virtual void A1(){cout<<"A::A1"<<endl;}
       void A2(){cout<<"A::A2"<<endl;}
};
class B:public A
{
public:
 virtual void A1(){cout<<"B::A1"<<endl;}
    void A2(){cout<<"B::A2"<<endl;}
    void A3(){cout<<"B::A3"<<endl;}
};

void main()
{
    A * pA = new B;
    B * pB = new B;

    pA->A1();  //B::A1()
    pB->A1();  //B::A1();

    pA->A2();  //A::A2();
    pB->A2();  //B::A2();

   

    //다운 캐스팅;
    //pA->A3(); //에러
    pB->A3(); ////B::A3(); 에러아님 자식인 B클래스부터 접근하기 때문에


   //업캐스팅
   cout<<"업캐스팅"<<endl;
   ( (A*)pB)->A2(); //A::A2();


   //다운캐스팅
   //pA->A3(); //에러었지만
   ((B*)pA)->A3();  ///B::A3();

 delete pA;
 delete pB;
}

'Programming > C/C++' 카테고리의 다른 글

TCHAR을쓰면 바뀌는 함수들  (0) 2010.07.27
TCHAR printf  (0) 2010.07.12
A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
Posted by blueasa

댓글을 달아 주세요


class에서 다중 상속을 받게 될 경우 그 부모의 함수를 호출하는데 부모 클래스의 이름이 필요하다.

이때 해당 클래스의 이름을 적지 않아도 __super 라는 키워드를 이용해 부모클래스를 찾아 해당

함수를 호출하도록 할 수 있다. 아래는 MSDN에 수록된 __super 의 사용 예다.

// deriv_super.cpp
// compile with: /c
struct B1 {
  void mf(int) {}
};

struct B2 {
  void mf(short) {}

  void mf(char) {}
};

struct D : B1, B2 {
  void mf(short) {
     __super::mf(1);   // Calls B1::mf(int)
     __super::mf('s');   // Calls B2::mf(char)
  }
};



'Programming > C/C++' 카테고리의 다른 글

TCHAR printf  (0) 2010.07.12
A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
Posted by blueasa

댓글을 달아 주세요

프로그램의 오류를 찾기 위해 가장 기본적으로 쓰는 기능 중 하나가 바로  assert 문 입니다.

 

사용법은 다음과 같지요.

 

#include <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL );               // 메모리가 할당되지 않았다면 메세지 박스와 함께 프로그램이 죽습니다.

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

보다시피 사용방법은 매우 직관적입니다.

 

assert( p != NULL ); 구문은 디버그 모드에서만 작동되며 p가 반드시 NULL이 아니어야 한다는 조건을 부여합니다. 따라서, p가  NULL 이라면 메세지 박스가 활성화 되면서 assert가 걸린 라인 수까지 표시가 되지요.

 

물론 릴리즈 모드로 컴파일하면 위의 구문들은 모두 생략됩니다.

 

 

 

이제, 기본적인 사용방법을 알았으니 추가적인 비법을 알려드리지요.

 

 #include  <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL && "포인터 메모리 할당을 실패했잖아" );             

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

결과는 메세지 박스에 "포인터 메모리 할당을 실패했잖아" 라는 문구까지 부가적으로 표시됩니다.

 

 

매우 간단한 반면 그 기능은 탁월합니다. 저 같은 경우는 항상 포인터 NULL  여부 및 인덱스 참조 시에  assert 문을 사용하곤 합니다만

 

여러분도 필요한 곳에 사용하시길 바랍니다.

[출처] assert 문 사용하기|작성자 Hermet


'Programming > C/C++' 카테고리의 다른 글

A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
Posted by blueasa
TAG assert

댓글을 달아 주세요

본 글을 읽기 전에 다음 글을 읽으시면 도움이 됩니다.  http://hermet.pe.kr/92422706 (c++ 예외처리), 

 

 

예전부터 궁금한 사실이었지만,   과연 try - catch를 사용함에 따른 비용은 어느정도일까?

 

궁금해서 직접 c++을 통해 테스트 해보기로 했습니다.

 

 #define ENABLE_EXCEPTION

 

struct Test {
      int    m[100];
      Test() { printf( "." ); }
 };

 

int _tmain(int argc, _TCHAR* argv[])
{

          DWORD begin = GetTickCount();

      

          for( int idx = 0; idx < 1000000; ++idx ) {

 #ifdef ENABLE_EXCEPTION
         try {
                Test* test = new Test();        delete( test );
         }catch( ... ) {    printf( "Exception!\n" );        }
 #else
         Test* test = new Test();
         delete( test );
#endif
}       

          DWORD end = GetTickCount();

          printf( "Elapsed - %d\n", end - begin );
          return 0;
}

 

위 코드에 대해 주목할 것은 어떤 임의의 루프문에서 Test라는 객체를 생성하고 제거하는 것인데,  예외처리 지정일 경우 try - catch 문에서 이를 수행한다는 것입니다.

 

그럼 과연 try-catch를 했을 경우와 하지 않았을 경우의 출력 값은 어떠했을까?

 

예외 처리한 결과 - 85723

안한 결과 -          76503

 

성능 결과는 무려 9초 차이가 납니다. 그리고 언어마다 그 차이는 조금씩 다르겠죠. (매우 클 수도 있고.. -_- )

 

그래도 확실한 것은,  try - catch에 의한 비용은 분명히 있습니다.

 

자, 어찌됐든 위 코드에서 우리는 메모리 할당의 예외 가능성을 예측할 수 있으므로 다음과 같이 수정해 봅시다.

 

 Test* test = new Test();

 

if( test ) {

    delete( test );

}else {

      printf( "Exception!\n");

}

 

그리고 시간 측정 결과는 다음과 같습니다.

 

예외 처리한 결과 - 85723

안한 결과 -          76503

나의 예외처리 -      78671

 

아무것도 하지 않는 것보다는 약 2초 가량 더 부하가 있긴 하지만, try-catch보단 월등히 낫군요.

 

사실, 시스템 사양에 따라 이런 예외처리 부하는 매우 미미할 수 있을 것이며 80:20 법칙을 고려했을 때도 이는 전체 성능에 거의 눈에 띄지 않을 수도 있겠죠.

 

결국, 예외처리에 대한  선택의 여지는 여러분의 몫이 될 수 밖에 없습니다.

 

 

그리고 예외처리에 대한 저의 철학은 다음과 같습니다.

 

 

"피할수 있다면 하지 않는다."

 

 

try-catch 문에 대해선 위 예와 같이 피할 수 있으면 하지 않습니다. 시스템 콜 사용에 대해선 결과를 알 수 있으므로 대부분 하지 않겠죠.

또한 라이브러리 제작 측면에서는 사용자의 잘못된 사용에 대해 if-else 대신 assert (http://hermet.pe.kr/54763810 )로 사전에 방지해 줍니다. 개발 과정에서는 debug 모드로 제작을 하면서 모든 에러 및 잘못된 사용에 대해 사용자들에게 assert로 알려주는 것이지요.

 

그리고 제품 release일 경우엔 이 assert문은 자연스럽게 코드에서 빠지면서 예외처리에 대한 부하도 같이 사라지게 됩니다.

물론 개발과정에서 assert문을 통해 모든 오류를 수정한 후 일것이구요.

 

More Effective C++ 책에 의하면, try - catch 블록을 쓰기만 해도 코드 블록 및 실행 속도가 5 ~ 10 % 늘어난다고 합니다.

또한, 실제 예외가 발생(throw)하여 함수로 복귀하는데에는 1000배 만큼 느려진다고 합니다. 물론 예외는 거의 발생하지 않는다 라고 봤을 때 이런 부하는 눈감아 줄 수도 있겠죠.

 

 

결론을 말하죠.

 

쓸데없이 예외처리를 하지는 마세요. 진짜 예외적인 상황이 발생할 수 있을 때만 합니다.

성능이 문제가 된다면 위 예제 소스와  같이 프로파일링을 해보세요.

그리고 컴파일러 옵션에서 예외지정을 제외하세요.

 

 

 

(참고 - More Effective C++ (정보문화사), 132-134 )


'Programming > C/C++' 카테고리의 다른 글

__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
TCHAR에 관한여...  (0) 2010.04.29
Posted by blueasa
TAG try-catch

댓글을 달아 주세요

소스를 보다가 소멸자가 순수 가상 함수로 선언 돼 있는데 정의 부분이 있어서 이게 뭔가..싶어서 검색해보고 답을 찾아서 링크..


질문 1]

순수 어쩌고 가상함수. 이렇게 명명되는 함수들은 정의가 없습니다.
그래서 이 함수를 포함하고 있는 클래스는 인스턴스를 만들 수 없죠.

그런데 EC++ (3/e)를 읽다보니 순수 가상 함수에 정의를 하고 있는 부분이 나옵니다.
항목7 93~94페이지에 나온 AWOV 클래스인데요,

class AWOV {
public:
  virtual ~AWOV() = 0;
};

이렇게 소멸자가 '순수 가상'으로 되어있음에도 불구하고, 다음 페이지에서

AWOV::~AWOV() {} // 순수 가상 소멸자의 정의

이렇게 정의를 내리고 있습니다.

제가 컴파일을 해보니 또 컴파일도 되더군요-_-; 어떻게 이런 문법이 가능한건가요?

질문 2]
역시 또 EC++(3/e) 항목 31 225페이지에 보면 인터페이스(Java의 그것과 유사한 의미)를 선언하고 있는데요,

class Person {
public:
  virtual ~Person();

  virtual std::string name() const = 0;
  ...
};

여기서는 소멸자를 '단순 가상'함수로 선언하고 있습니다.

왜 '순수 가상'으로 만들지 않는 것인지 의문이 생깁니다.
이 클래스는 '추상 클래스'가 아닌 '인터페이스'로 쓸 것인데 말이죠...

구글링 등 검색을 해봐도 만족할 만한 답변을 얻을 수 없어서 질문 드립니다~


질문도 그렇고 답변도 좀 길 듯하여^^ 별도의 답글로 달아 봤습니다.

질문 1에 대한 답변

C++에서 순수 가상 함수의 기계적 의미는 해당 추상 클래스의 vtbl에서 그 순수 가상 함수의 포인터가 0(=null)로 들어 있다는 것입니다. 즉, AWOV 클래스가 이렇게 되어 있다면,

class AWOV { public: virtual ~AWOV()=0;  virtual foo(); };

이 클래스의 vtbl은 다음과 같이 나옵니다.

vptr -> [ 0                   ]   // 첫째 : AWOV::~AWOV()의 주소
           [ &(AWOV::foo)]   // 둘째 : AWOV::foo()의 주소

하지만, 가상 소멸자의 호출 매커니즘은 파생 클래스의 소멸자가 기본 클래스의 그것을 직접 호출하도록 (컴파일러에 의해) 만들어집니다. vtbl을 통하지 않는다는 것이죠. 따라서 AWOV::~AWOV의 본문이 정의되어 있지 않으면 링크 에러를 내게 됩니다. 이것은 "이렇게 해도 컴파일이 되네" 수준이 아니라 "꼭 이렇게 해야 합니다"라는 의무 조항입니다.

질문 2에 대한 답변

설계상의 선택사항입니다. 순수 가상 함수로 만들 다른 함수가 있으면 구태여 소멸자를 순수 가상으로 만들 필요 없이 비순수 가상으로 만들어도 됩니다.


출처 : http://www.kwak101.pe.kr/bbs/view.php?id=kwk_worksBBS&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=157

'Programming > C/C++' 카테고리의 다른 글

[펌] assert 문 사용하기  (0) 2010.05.13
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
TCHAR에 관한여...  (0) 2010.04.29
[C]#pragma - once, pack, warning, comment, link  (0) 2010.04.16
Posted by blueasa

댓글을 달아 주세요

  1. 2014.04.12 09:12  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • 2014.04.14 13:50 신고 blueasa  댓글주소  수정/삭제

      예전에 궁금해서 찾아봤었는데 리플 덕분에 다시 한 번 확인하게 되네요.
      도움 되셨다니 즐겁습니다.
      좋은 하루 되세요. ^^


'Programming > C/C++' 카테고리의 다른 글

[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
TCHAR에 관한여...  (0) 2010.04.29
[C]#pragma - once, pack, warning, comment, link  (0) 2010.04.16
다른방식의 싱글톤  (0) 2010.04.15
Posted by blueasa
TAG assert

댓글을 달아 주세요

출처 : http://alpu.egloos.com/2968362/

Type       Size                                Support             end of string
-----------------------------------------------------------------------
SBCS       1byte                              win9X, NT              \0
-----------------------------------------------------------------------
MBCS       1byte(영문), 2byte(한글)   winNT                   \0
-----------------------------------------------------------------------
UNICODE    2byte                            winNT,CE              \0\0
-----------------------------------------------------------------------

Unicod와 MBCS/ANSI에 따라서 따로 구분해서 프로그램할 필요가 없도록 하기위해서
사용하는 것이 TCHAR 매크로임
즉, TCHAR 타입이 _UNICODE가 정의된 경우에는 wchar_t 타입으로 작동하고,
_MBCS가 정의된 경우에는 char 타입으로 작동한다.

(TCHAR 을 나타는 매크로가 _T 이다. (한문자 _T(' '), 문장 _T(" "))

#include <tchar.h>
#define _UNICODE   // ==> TCHAR를 wchar_t 형으로 대치

#define _MBCS       // ==> TCHAR를 char 형으로 대치 (default)



[ 타입 정의 ]
#ifdef UNICODE
       typedef wchar_t TCHAR;  // 2byte
#else
       typedef char TCHAR;       // 1byte
#endif

[ 함수 정의 ]
#ifdef UNICODE
      typedef SetWindowTextW SetWindowText;
#else
      typedef SetWindowTextA SetWindowText;
#endif



UNICODE가 정의 되면,
--------------------------------------------------------
TCHAR == wchar_t
TEXT == _TEXT == L



_UNICODE가 정의 되면,
--------------------------------------------------------
TCHAR == wchar_t
_T == __T == _TEXT == L


따라서 UNICODE, _UNICODE가 모두 정의 되어야 한다.


_MBCS가 정의 되면,
--------------------------------------------------------
TCHAR == char
_T == __TEXT == 사라짐



UNICODE, _UNICODE, _MBCS 중 어느것도 정의 되지 않으면,
--------------------------------------------------------
TCHAR == char
_T == __TEXT == 사라짐




[ 예) 상수 문자열 ]

LPTSTR  lpszStr = "My string";           // 문자열을 ANSI 문자열로 간주,
                                                    // 데이터형 불일치로 에러가 발생한다.

TCHAR   *lpszStr = T("My string");
LPTSTR  lpszStr = _T("My string");     // _UNICODE가 정의되어 있으면 _T()는 유니코드
                                                     // 문자열 상수로 변환하고, _MBCS가 정의되어 있으면
                                                     // ANSI 문자열 상수로 변환한다.

LPTSTR  lpszStr = TEXT("My string"); // 상동

LPWSTR  lpszStr = L("My string");       // 유니코트 문자열로 지정하는 매크로 함수 L()



[ 예) 문자열 버퍼 길이 계산 ]

#define _UNICODE

TCHAR szBuffer[200];                               // szBuffer의 크기는 400 bytes

DWORD dwlen;
dwlen = sizeof(szBuffer);                           // 400 bytes
dwlen = sizeof(szBuffer) / sizeof(TCHAR);  // 실제 저장 가능한 유니코드 문자 개수는 200개



[ 예) 표준 문자열 라이브러리 함수 ]

표준 C 런타임 함수 strlen()에 해당하는 유니코드 함수는 wcslen()이지만,
_tcslen()을 사용하면 _UNICODE, _MBCS 정의에 따라 컴파일시에 알아서 적절히 변환된다.
(tchar.h에 다 정의되어 있다.)

ANSI            Unicode          TCHAR type
--------------------------------------
strlen()        wcslen()         _tcslen()
strcat()        wcscat()         _tcscat()
strchr()        wcschr()         _tcschr()
strcmp()      wcscmp()       _tcscmp()
strcpy()       wcscpy()        _tcscpy()
strstr()         wcsstr()          _tcsstr()
strrev()        _wcsrev()        _tcsrev()

printf()         wprintf()           _tprintf()
sprintf()       swprintf()         _stprintf()
scanf()        wscanf()          _tscanf()



[ 예) ANSI 문자열과 Unicode 문자열 간의 변환 ]

(1) Multi-Byte String을 Wide Character String(유니코드)으로 변환
               mbstowcs(WCHAR *des, char *src, int BufferSize);

(2) Wide Character String(유니코드)을 Multi-Byte String으로 변환
               wcstombs(char *des, WCHAR *src, int BufferSize);



[ 타입 정의 ]

typedef CHAR *   LPSTR, *PSTR;
        CHAR * == LPSTR == PSTR

typedef CONST CHAR * LPCSTR, *PCSTR;
        CONST CHAR * == LPCSTR == PCSTR

LPTSTR   = TCHAR *

LPCTSTR = CONST TCHAR *

'Programming > C/C++' 카테고리의 다른 글

[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
TCHAR에 관한여...  (0) 2010.04.29
[C]#pragma - once, pack, warning, comment, link  (0) 2010.04.16
다른방식의 싱글톤  (0) 2010.04.15
조건문의 최적화 방법  (0) 2010.04.14
Posted by blueasa
TAG TCHAR

댓글을 달아 주세요