보통 아무 생각없이 사용하는 MFC 클래스로 입출력 처리를 담당하는 CArchive와 문자열을 관리하는 CString 클래스가 있습니다.
그런데 CArchive를 이용하여 CString 문자열을 내보내면 어떤 결과가 발생하는지 아십니까?
다음과 같은 예제를 Visual C++ 에서 실행해 보십시오.
예제는 파일을 생성 후 "hello" 문자열을 저장하는 단순한 구조입니다.
그러면 예제에서 파일은 실제 어떻게 저장될까요?
다음과 같이 저장된다고 예상하는 이들이 많을 것입니다.
파일 크기: 5바이트
하지만, 의외로 결과는 6 바이트이고, 첫바이트에 글자 길이가 적히며 후에 hello가 저장됩니다.
왜냐고요?
이는 CArchive의 연산자(operator)인 << 의 소스 코드를 보면 알 수 있습니다.
내용을 보면 AfxWriteStringLength() 라는 함수가 사용됩니다.
이 코드의 소스를 자세히 봅니다.
이제는 이해가 될지도 모르겠습니다.
3열의 유니코드(Unicode) 처리를 봅시다.
(현재 대부분의 Windows 개발 환경은 64비트(x64)와 유니코드이므로, 일단 MBCS(Multi Byte Character Set)일 경우는 넘어 가겠습니다.)
10열을 보면 문자열의 길이가 255보다 작으면 문자열 길이를 적어 주는 기능이 있습니다.
그리고 문자열의 길이에 따라서 문자열 길이를 적어 주는 방식이 약간씩 다른 것도 알 수 있습니다.
길이가 65535보다 크면, 0xff(=255)를 적고 길이를 적습니다.
그리고 유니코드가 적용되면 ff ff fe 를 먼저 적고, 처리를 시작합니다.
물론 파일을 읽는 함수인 AfxReadStringLength() 는 이 처리의 역과정을 거치고, CArchive의 loading 연산자에서 사용됨도 확인 가능합니다.
아주 단순한 내용이지만, 이제는 왜 CArchive/CString을 이용시에 null-terminated 방식으로 파일이 저장되지 않는지를 알 수 있을 것입니다.
MFC와 마찬가지로 Delphi/C++ Builder의 VCL, C++를 사용하는 Qt,Boost,Ace 등을 이용하실 경우에도 내부 소스(Internal Source)를 보아야 정확한 기능이 이해되는 경우가 많습니다. MFC는 과거에 출간되었던 MFC Internals 라는 책자를 보시면 유용합니다. 책을 보시면 Microsoft 개발팀의 놀라운 능력과 치부(?)를 동시에 보실 수 있습니다.