C - 해당되는 글 1건

BSTR은 비주얼 베이직에서 사용하는 문자열 형식입니다. 'Basic String' 혹은 'Binary String'의 약자로 흔히 알려져 있습니다. C나 C++류의 프로그래밍 언어만 다루던 사람들은 당연히 문자열은 끝이 0으로 끝나는 문자들의 배열로 생각합니다. 그런데, 문자열들은 보통 'null-terminated string' 또는 'C-style string'이라고 말합니다. 즉, 문자열을 나타내는 방법의 하나일 뿐입니다. 뭐, 다른 언어에서는 어떻게 표현하는 지 모르겠지만,,, 문자열이라는 자료형이 존재하지 않는 C류의 프로그래밍 언어는 배열을 사용해서 문자열을 나타내기에 저렇게 된 것입니다.

 

그럼 왜 C와 C++에서 BSTR을 사용하게 되었는가를 알아봐야겠지요?

 

내가 만드는 프로그램이 C++ 언어로만 구현이 되었다면, 다른 언어가 어떻게 생겼든 알 바 아닙니다. 그런데, 요즘은 이런저런 프로그램들이 얽히고 섥혀서 돌아갑니다. MS 워드에 MS 엑셀의 표가 들어가고, 그 표를 더블클릭하면 MS 엑셀의 편집 화면이 워드 안에 생깁니다. 비주얼 베이직 스크립트로 MS 워드의 동작을 막 자동화할 수도 있죠. 이런 복잡한 예가 아니더라도, 비주얼 베이직으로 짠 프로그램이 내가 만든 C++ 프로그램의 기능을 이용하거나, 그 반대가 될 수도 있습니다.

OLE, 자동화, COM 뭐 이런 개념들입니다. 그 말많은 ActiveX도 이러한 류의 기술입니다. 이것들은 여기서 다룰 주제는 아니니 넘어갈게요. (물론, BSTR에 대해 궁금한 분들 대부분이 COM과 같은 것을 공부하는 분들일테니 굳이 안다루어도 되겠죠??)

 

MS에서 아주 강하게 미는 프로그램 개발 환경이 있습니다. 바로 비주얼 베이직이지요. (요즘에는 C#을 미는 것 같지만) 위에서 서로 다른 프로그래밍 언어들이 데이터를 주고 받을 필요가 생겼다고 말씀드렸죠? 기본적인 숫자 형식은 어느 프로그래밍 언어나 대동소이하니까 그냥 쓸 수 있다고 하더라도 다른 것들은 좀 문제가 있습니다. 그 중에서도 기본 숫자 형식들만큼이나 자주 쓰는 것이 문자열이죠.

 

이제 감이 오셨을 것입니다. 왜 BSTR이 사용되는지. 이와 비슷한 이유로 VARIANT나 SAFEARRAY 등도 쓰이는데, 마찬가지로 모두 비주얼 베이직에서 쓰는 자료형입니다.

 

그럼 이제 BSTR이 어떻게 생겼는지 보죠.

  1. typedef WCHAR OLESTR;
  2. typedef OLESTR FAR * BSTR;

WCHAR이라는 것 역시 재정의된 타입 이름인데, 호환성을 위해 short이나 wchar_t 등이라고 보시면 됩니다.

 

bstr-structure(1).gif

  • 앞의 4 바이트 부분은 뒤의 문자열이 몇 개의 문자로 이루어져 있는지를 적는 곳입니다.
  • 중간은 2-byte짜리 문자로 이루어진 배열입니다. 2-byte라는 것이 중요합니다. 최근의 C/C++ (C99 이후)들은 유니코드를 지원하기 위해서 2 바이트짜리 문자형인 wchar_t가 기본적으로 제공됩니다. 뭐 그렇지 않다고 하더라도 우리는 short이라는 자료형이 있으므로 걱정 없습니다.
  • 마지막 2 byte는 0입니다. 이것은 C 스타일의 문자열과 똑같죠. 주의할 것은 BSTR이 2바이트 문자형의 배열이므로 문자열 끝 기호 역시 2바이트로 0입니다. 보통 이 부분을 'Terminator'라고 부릅니다.

 

그런데 재미있는 것은 BSTR이라는 포인터형이 가리키는 곳입니다.

bstr-point(1).gif 

그림처럼 전체의 맨 앞이 아니라 문자가 시작되는 곳을 가리키고 있습니다.

 

그렇다면 이것은 안되겠네요!

  1. BSTR  bstrArtist = L"Muse";

안되는 이유 아시죠?

 

그럼 어떻게 BSTR 문자열을 만들까요?

 

이런 식으로 해볼 수도 있겠네요!

  1. wchar_t* wszArtist = L"Muse";
  2. BSTR bstrArtist = NULL;
  3. unsigned long* pLPrefix = NULL;
  4.  
  5. /* number of chars in wszArtist + size of legnth prefix + size of terminator */
  6. bstrArtist = malloc(wcslen(wszArtist) * sizeof(wchar_t) + 4 + 2);

     

  7. lPrefix = (unsigned long*) bstrArtist;
  8. *lPrefix = wsclen(wszArtist);
  9. bstrArtist += 4/sizeof(wchar_t);
  10. wcscpy(bstrArtist, wszArtist);

이렇게 해서 안될 건 없습니다.

 

문제는 프로그램간 데이터 전송이라는 것입니다. 그래서 특수한 방법으로 메모리를 할당받아야 합니다.

 

이에 대해서는 다음 포스팅에서 다루지요 ^^

 

참고 : MSDN

 

 

이 글은 스프링노트에서 작성되었습니다.

Trackbacks  0 | Comments 

풀리비’s Blog is powered by Daum & Tattertools.com