제프리 리처의 WINDOWS VIA C/C++
https://www.yes24.com/Product/Goods/3205340
페이지 41p ~ 68p
41p ~ 68p
요약
- Chapter02 문자와 문자열로 작업하기가 시작되는 부분이다.
- 이 책에서는 유니코드와 안전 문자열 함수를 사용하고 있으며, 이는 애플리케이션의 지역화를 좀 더 쉽게 하고, COM이나 닷넷 프레임워크와의 상호운용에도 도움을 줄 수 있게 된다.
section01 문자 인코딩
- 애플리케이션 지역화를 수행할 때 발생하는 전형적인 문제의 원인은 다양한 문자 집합 고려에 있다.
- 윈도우는 유니코드 문자를 UTF-16으로 인코딩한다.
- UTF-16은 각 문자를 2바이트로 구성한다.
- 이 책에서 유니코드라고 하면 다른 언급이 없는 이상 UTF-16 인코딩을 의미한다.
- 닷넷 프레임워크는 모든 문자와 문자열을 UTF-16으로 인코딩한다.
section02 ANSI 문자와 유니코드 문자 그리고 문자열 자료형
- C언어의 char 자료형은 8비트의 ANSI 문자를 표현하기 위해 존재한다.
// 8비트 문자 char c = 'A';
// 99개의 8비트 문자 + 널문자
char szBuffer[100] = "A String";
- 최근의 마이크로소프트 C, C++ 컴파일러는 16비트 유니코드를 표현하기 위한 `wchar_t` 자료형을 내장 자료형으로 처리할 수 있는 기능이 추가되었다.
```cpp
// 16비트 문자
wchar_t c = L'A';
// 99개의 16비트 문자 + 널문자
wchar_t szBuffer[100] = L"A String";
- 문자열 앞에 대문자 L은 컴파일러가 문자열을 유니코드로 다루도록 한다.
- 컴파일러가 문자열을 데이터 섹션에 삽입할 때 UTF-16으로 인코딩된다.
- 위의 코드에서는 모두 ASCII 문자이므로 남는 공간에 0이 삽입된다.
section03 윈도우 내의 유니코드 함수와 ANSI 함수
- 윈도우 NT 이후의 모든 윈도우 버전은 유니코드를 바탕으로 작성되었다.
- 창 생성, 텍스트 출력, 문자열 다루기 등 모든 핵심 함수들은 유니코드 문자열을 요구한다.
- ANSI 문자열을 전달한다면, 이를 유니코드로 변경하고 운영체제에게 전달한다.
- 윈도우는 문자열 인자를 가지는 함수를 제공하는 경우 일반적으로 동일한 함수를 두 가지 버전으로 제공한다.
// 유니코드 문자열 HWND WINAPI CreateWindowExW();
// ANSI 문자열
HWND WINAPI CreateWindoeExA();
// 일반적으로 사용하는 함수
// WinUser.h에 정의되어 유니코드 사용 여부에 따라 위의 함수 구분하여 호출
CreateWindowEx();
```
- 앞서 말했듯이 윈도우는 ANSI 문자열을 전달하면 이를 유니코드로 변환하는 작업을 추가적으로 수행하기 때문에
CreateWindowExA
를 호출하면 내부적으로 ANSI 문자열을 유니코드로 변경하고CreateWindowExW
를 호출한다. - 따라서 처음부터 유니코드를 사용하는 방향으로 애플리케이션을 개발하는 것이 좋다.
section04 C 런타임 라이브러리 내의 유니코드 함수와 ANSI 함수
- C 런타임 라이브러리도 ANSI 문자와 유니코드 문자를 다루는 함수를 세트로 제공한다.
- 다만 윈도우에서 제공하는 함수와는 다르게 ANSI 버전의 함수들도 정상적으로 작동하며, 내부적으로 유니코드 변환도 수행하지 않는다.
section05 C 런타임 라이브러리 내의 안전 문자열 함수
- 문자열을 다루는 함수들은 항상 잠재적인 위험에 노출되어 있다.
strcpy
,wcscpy
함수는 버퍼의 최대 크기를 인자로 받지 않기 때문에 메모리에 문제가 생겨도 에러를 보고받을 수 없고, 메모리가 정상적으로 운용되고 있는지 알 방법도 없다.- 안전한 코드를 작성하고 싶다면 C 런타임 라이브러리 내의 문자열 조작 함수는 더 이상 사용하지 않는 것이 좋다.
strlen
,wcslen
,_tcslen
등과 같이 전달된 문자열을 수정하지 않는 함수들은 사용해도 된다.- 그래도 좋은 방법은
StrSafe.h
를 통해 새롭게 제공되는 안전 문자열 함수를 사용하는 것이다.
section06 왜 유니코드를 사용하는 것이 좋은가?
- 다른 나라의 언어로 지역화하기 쉽다.
- 단일의 바이너리 파일로 모든 언어를 지원할 수 있다.
section07 문자와 문자열 작업에 대한 권고사항
- 문자열을 char 타입이나 byte의 배열로 생각하지 말고 문자의 배열로 생각
- 문자나 문자열을 나타낼 때 중립 자료형(TCHAR/PTSTR)을 사용
- 바이트나 바이트를 가리키는 포인터, 데이터 버퍼 등을 표현하기 위해서는 명시적인 자료형(BYTE, PBYTE)를 사용
- 문자나 문자열 상수 값을 표현할 때에는
TEXT
나_T
매크로를 사용. 일관성과 가독성을 유지하기 위해 두 개의 매크로를 혼용해서는 안 된다. - 산술 계산 부분을 수정(바이트 단위가 아닌 문자 단위로 계산)
sizeof(szBuffer) -> _countof(szBuffer)_
malloc(chars) -> malloc(chars * sizeof(TCHAR)
: 메모리 할당은 바이트 단위로 수행
- 문자열을 다루는 함수는 이름이
_s
로 끝나거나StringCch
로 시작하는 안전 문자열 함수 사용 - Kernel32가 제공하는 lstrcat, lstrcpy 등의 문자열 관련 함수 사용 금지
- 문자열 비교는 다음과 같은 방법을 사용
- 프로그램 내에서만 주로 사용하는 파일명, 경로명, XML 요소, 레지스트리 등:
CompareStringOrdinal
- 사용자의 언어 설정을 고려하지 않기 때문에 빠름
- 사용자의 유저 인터페이스를 구성하는 문자열:
CompareString(EX)
- 문자열을 비교할 때 사용자의 언어 설정을 고려
- 프로그램 내에서만 주로 사용하는 파일명, 경로명, XML 요소, 레지스트리 등:
section08 유니코드 문자열과 ANSI 문자열 사이의 변경
- MultiByteToWideChar
'책 > 제프리 리처의 WINDOWS VIA C, C++' 카테고리의 다른 글
WINDOWS VIA C/C++(31p ~ 41p): Chapter01 에러 핸들링 (1) | 2024.01.04 |
---|---|
WINDOWS VIA C, C++(0p ~ 30p) (1) | 2024.01.04 |