'Program'에 해당되는 글 71건

  1. 2008.01.16 문자열에 대한 정리
  2. 2008.01.16 CWaitCursor, GetTempFileName, LoadLibary, GetProcAdress
  3. 2008.01.16 마우스 위치에 따른 포인터 값으로 윈도우 식별하기..
  4. 2008.01.16 Using the System Device Enumerator
  5. 2008.01.16 IAMAudioInputMixer Interface
  6. 2008.01.16 비디오 캡쳐 예제
  7. 2008.01.16 Multimedia Streaming Synchronization Mechanisms Under DirectShow
  8. 2008.01.16 그래프 스파이 기능. AddGraphToROT
  9. 2008.01.16 VC - 1 이란
  10. 2008.01.16 GExport

문자열에 대한 정리

Program/C | C++ 2008. 1. 16. 09:39

출 처 :
백택 (bektekk@yahoo.co.kr)
홈페이지 : http://bektekk.wo.to

문자열(스트링) 전격 분석 2부 1강

본강좌는 코드 프로젝트에 제가 좋아하는 프로그래머인 Michael Dunn의 강좌
The Complete Guide to C++ Strings, Part I 과 II 를 번역한 글입니다.
최대한 의역을 하려고 노력했지만, 이런쪽의 경험이 부족하다 보니 많이 모자란
강좌가 되겠지만, 많은 도움이 되셨으면 합니다.
기타 문의 사항이나 질문은 쪽지나 메일을 이용해 주셨으면 합니다.
본강좌는 제 홈페이지(위의 링크)를 통해서도 보실수 있습니다.

이번강 까지도 좀 지루하겠네요.
다음강을 마지막으로 실제 클래스들을 다루어 보겠습니다.

소개

C스타일 스트링은 에러를 유발하기 쉽고, 관리하기가 매우 까다로울뿐만 아니라, 해커에게 오버런 버그를 노출하는 타겟이 될 수도 있기 때문에, 수많은 스트링 랩퍼 클래스들이 생겨났다. 하지만 불행히도 어떤 상황에서 어떤 클래스를 써야하고 혹은 C스트링을 어떻게 랩퍼 클래스를 이용해 처리해야 하는지는 가끔씩 우리를 해깔리게 한다.

이번 강좌 2부의 내용은 Win32 API, MFC, STL, WTL과 VC런타임 라이브러리의 모든 스트링 랩퍼 클래스들을 다루고 있다. 각 클래스는 어떻게 생성하고 사용하며, 각각 어떻게 변환할수 있는지 설명할 것이다.

2부의 내용을 제대로 소화하기 위해서는 1부 1,2강에서 설명한 캐릭터 타입들과 인코딩 방식에 대한 충분한 이해가 필요할 것이다.

스트링 클래스의 가장 중요한 규칙

만약 문서화되어 있어 형변환에 문제가 없다는 확신이 없으면 강제 형변환은 피할것.

어떤 스트링랩퍼 클래스 X와 또다른 클래스 Z사이의 형변환에 관한 내용은 특히 초급 프로그래머들이 많이 궁금해 하는 내용이다. 주로 초급 프로그래머들은 강제 형변환을 시도한 후 왜 제대로 동작하지 않는가에 대해 많이 궁금해 하곤 한다. 수많은 스트링 타입들, 특히 BSTR 같은 타입은 명확히 문서화 되어있지 않은 게 현실이다. 따라서 많은 사람들은 쉽게 잘못된 코드를 작성할 가능성이 많았다.

무엇보다 중요한 점은 랩퍼클래스에서 형변환 연산자를 재정의 하지 않았다면 형변환은 사실 스트링 사이에서 아무 일도 하지 않는다. 그래서 만약 아래와 같은 코드를 작성 했다면:

void SomeFunc ( LPCWSTR widestr ); main(){  SomeFunc ( (LPCWSTR) "C:\\foo.txt" );  // WRONG!}

위의 코드는 백이면 백 잘못된 결과를 초래할 것이다. 사실 위의 코드는 에러 없이 컴파일 된다. 하지만 컴파일이 된다고 그 코드가 옳바르다고 장담할수는 없는 것이다.

강의를 진행하면서 어떤 형변환이 옳바른 것인지 설명하도록 하겠다.

C-style strings and typedefs

지난 강의에서 살펴 보았듯이, Win API는 TCHAR 방식으로 정의되 있다. 그것은 컴파일 시에 문맥에 따라 MBCS방식으로 전환될수도 있고, 유니코드가 될수도 있다. 편의를 위해 지난 강의에 보여줬던 표를 다시 보여 주도록 하겠다.

타입 MBCS환경에서 유니코드 환경에서
WCHAR wchar_t wchar_t
LPSTR 0으로 끝나는 char형의 문자열(char*) 0으로 끝나는 char형의 문자열 (char*)
LPCSTR 0으로 끝나는 const char형의 문자열 (const char*) 0으로 끝나는 const char형의 문자열 (const char*)
LPWSTR 0으로 끝나는 유니코드형의 문자열 (wchar_t*) 0으로 끝나는 유니코드형의 문자열 (wchar_t*)
LPCWSTR 0으로 끝나는 const 유니코드형의 문자열 (const wchar_t*) 0으로 끝나는 const 유니코드형의 문자열 (const wchar_t*
TCHAR char wchar_t
LPTSTR 0으로 끝나는 TCHAR형의 문자열 (TCHAR* -> char* 0으로 끝나는 TCHAR형의 문자열 (TCHAR*->wchar_t*)
LPCTSTR 0으로 끝나는 const TCHAR형의 문자열 (const TCHAR*) 0으로 끝나는 const TCHAR형의 문자열 (const TCHAR*)

타입을 하나 추가 하자면 OLECHAR을 들수 있겠다. 이 타입은 주로 자동화 인터페이스에서 사용된다. 이 타입은 보통 wchar_t 으로 정의되 있으나, 셋팅을 변경하거나 #define 문으로 OLE2ANSI 를 정의하면 단순 char 타입으로 전환된다. 하지만 사실상 요즘엔 OLE2ANSI 를 적용할 이유는 없다. (사실, MFC3 버젼에서 사용되어졌던 것이다. 구시대의 유물^^), 따라서 지금부터 그냥 단순히 OLECHAR 타입을 유니코드로 간주할 것이다.

아래의 표는 OLECHAR 와 관계된 typedef 문으로 정의된 데이터 타입을 보여준다. :

타입 의미
OLECHAR 유니코드 케릭터 (wchar_t)
LPOLESTR 유니코드 스트링 (OLECHAR*)
LPCOLESTR const 형 유니코드 스트링 (const OLECHAR*)

문자열을 다룰 때 유니코드 MBCS 방식에 관계없이 일관된 표현을 할수 있게 해주는 두가지 마크로가 있다. _T 마크로는 지난 강의에서도 다루었던 부분이다. :

마크로 의미
_T(x) L 유니코드빌드일때 L을 앞에 주가해 준다.
OLESTR(x) LPOLESTR 타입으로 만들기 위해 L을 앞에 추가해 준다.

또한 _T에서 변형된 형태의 하지만 같은 역활을 하는 몇몇 마크로 들이 더 있다. -- TEXT, _TEXT, __TEXT, and __T 이 마크로 들은 모두 같은 일을 한다.

COM에서의 스트링 - BSTR

많은 자동화객체 인터페이스나 COM 인터페이스는 스트링으로 BSTR 타입을 사용한다. 하지만 BSTR타입은 다루기 매우 까다롭고, 에러를 유발하기 쉽다. 따라서 BSTR을 이번 파트에 다뤄 보도록 하겠다.

BSTR 타입은 파스칼 스타일의 스트링과 C 스트링 사이의 잡종 즉 서로 짬뽕되서 생긴 타입이다. 파스칼에서는 문자열타입에 그 길이가 내부적으로 저장된다. 하지만 C스트링에서는 마지막 제로바이트를 통해서 그 문자열의 끝을 알수있게끔 되어 있다. 사실 BSTR 타입은 문자일 길이를 문자열 시작 바로 전에 저장하고 이어서 유니코드 스트링을 저장하는 방식의 타입니다. 또한 제로바이트로 그 끝을 표시한다. 아래는 "Bob" 이라는 BSTR 타입의 스트링의 메모리 구조를 보여준다.:

06 00 00 00  42 00  6F 00  62 00  00 00

길이

B

o

b

스트링끝

눈치채셨다 시피 문자열의 길이가 DWORD타입으로 (즉 4바이트) 실제 문자 앞에 저장된다. 하지만 이는 마지막 00 00의 제로바이트를 포함하지 않은 길이 이다. 위의 경우 "Bob" 문자열은 총 6바이트의 3개의 유니코드 캐릭터를 가지고 있다. 길이 정보를 포함하는 이유는 COM 라이브러리가 다른 곳으로 마샬링 될때 얼마나 많은 바이트를 보내야 하는지 그 정보가 필요하기 때문이다. (사실, BSTR 은 단지 스트링뿐만 아니라 임의의 어떤 데이타가 들어 있어도 상관이 없다.)

BSTR 변수는 C++에서 첫번째 캐릭터를 가리키는 포인터 변수 이다. BSTR 타입은 이렇게 정의 되있다. :

  typedef OLECHAR* BSTR;

불행히도 이런방식의 정의는 많은 문제를 유발할수 있다. 위에서도 설명했듯이 실제로는 BSTR은 유니코드 스트링과는 다른 특성을 가진 타입이다. 따라서 BSTR과 LPOLESTR은 마음대로 섞어 써도 컴파일러는 에러를 발생하지 않는다. LPOLESTR을 인자로 받는 함수에 BSTR 타입을 전달하는 것은 안전하다. 그렇지만 그 반대의 경우는 다르다. 따라서 함수가 받는 인자의 타입을 정확히 알고 정확히 전달하는 것이 중요하다.

BSTR 타입을 받는 함수에 LPOLESTR을 전달하는것이 왜 안전하지 못하냐 하면, BSTR이 가리키는 메모리 바로 앞 4바이트는 그 문자열의 길이를 포함하는 정보를 담고 있어여 한다. 아마 BSTR을 받는 함수에서는 그 정보가 포함되 있다는 가정하에 그 정보를 이용할 것이다. 하지만 LPOLESTR 타입에는 그러한 정보는 없다. 이는 안전하지 못한 결과를 낳을 것이다. 위에서 말했다 시피 COM객체에서는 BSTR 의 문자열 앞에 존재하는 문자열길이 정보를 이용해 그 만큼의 데이터를 전송한다고 있다. BSTR대신 LPOLESTR을 전달하면 얼마만큼의 바이트가 전송될지는 아무도 장담할 수가 없게 되는 것이다.

따라서 BSTR을 다루기 위한 몇몇 API들이 존재하지만 그중 가장 중요한 것은 두가지 이다. 하나는 BSTR을 생성시키기 위한 것이고, 다른하나는 제거하기 위한 것이다. BSTR을 생성하는 함수는 SysAllocString() 이고 제거하는것은 SysFreeString()이다.  SysAllocString() 은 매개변수로 받은 유니코드 스트링을 BSTR형태로 만들어 주는 역할은 한다. (새로운 메모리를 할당한 후에 아마 문자열 길이를 계산해서 문자열 앞에 그 길이정보를 추가해 주는 정도의 일을 할 것이다.) 반면 SysFreeString()BSTR 을 메모리에서 제거하는 역할을 한다.

BSTR bstr = NULL;   bstr = SysAllocString ( L"Hi Bob!" );   if ( NULL == bstr )    // 메모리가 부족   // bstr을 마음껏 사용^^   SysFreeString ( bstr );

사실, 스트링 하나 사용하겠다고 이런 일련의 함수를 계속적으로 사용하는 것은 굉장히 피곤하다. 따라서 자연스럽게 메모리 할당, 제거를 자동적으로 해주는 몇몇 랩퍼 클래스들이 생겨나게 됐다. 그에 대해서 뒤에 살펴보기로 하자

:

CWaitCursor, GetTempFileName, LoadLibary, GetProcAdress

Program/C | C++ 2008. 1. 16. 09:38
CWaitCursor    모래시계 커서

GetTempFileName    임시파일 생성
        ( 경로, 파일명일부 텍스트, 0, 생성될 파일명을 저장할 메모리 주소)

LoadLibary    DLL로드
        (경로명)

GetProcAdress    유요한 DLL함수 주소
        (Dll 핸들, 함수명 )
:

마우스 위치에 따른 포인터 값으로 윈도우 식별하기..

Program/C | C++ 2008. 1. 16. 09:38
 마우스 위치에 따른 포인터 값으로 윈도우 식별하기..

# 마우스 위치값 만을 가지고 MDI 구조내 차일드 윈도우들을 식별하는 루틴..

# 생각 과정에서의 시행 착오..
PtVisible    : 클립핑 영역에 마우스 포인터가 위치하는가 ?
PtInRect    : 해당 랙트내 마우스 포인터가 위치하는가..
MouseHover    : 이벤트로서 윈도우 위에 마우스 포인터가 위치할 경우 윈도우에 전달된다...
    닷넷 이상의 환경이나 컴포넌트 기반의 언어에서 지원하는 듯 하다.
ScreenToClient, ClientToScreen    : 장치적, 논리적인 마우스의 위치값
GetCurPos    : 마우스 위치값
FromHandle    : 핸들값으로 윈도우 포인터값을 얻는다

# 찾아낸 결과
WindowFromPoint, ChildWindowFromPoint    : 마우스 포인터값을 이용한 윈도우 핸들, 포인터

첨부 파일은 샘플 코드로서 타이머가 10초 단위로 마우스포인터가 놓인 차일드 윈도우의 타이틀을 리턴하게 만들었다.

# 비고
샘플 파일을 테스트 도중 디테일하게 윈도우 핸들을 구별해 내지 못하는 듯 하다...
다른 루틴을 고민해 볼 필요성이 보인다.

'Program > C | C++' 카테고리의 다른 글

응용프로그램 경로 알기  (0) 2008.01.16
문자열에 대한 정리  (0) 2008.01.16
CWaitCursor, GetTempFileName, LoadLibary, GetProcAdress  (0) 2008.01.16
:

Using the System Device Enumerator

Program/Direct Show 2008. 1. 16. 09:36

'Program > Direct Show' 카테고리의 다른 글

IAMAudioInputMixer Interface  (0) 2008.01.16
비디오 캡쳐 예제  (0) 2008.01.16
Multimedia Streaming Synchronization Mechanisms Under DirectShow  (0) 2008.01.16
:

IAMAudioInputMixer Interface

Program/Direct Show 2008. 1. 16. 09:35
:

비디오 캡쳐 예제

Program/Direct Show 2008. 1. 16. 09:34
:

Multimedia Streaming Synchronization Mechanisms Under DirectShow

Program/Direct Show 2008. 1. 16. 09:34
랜더링시 오디오 스트림과 비디오 스트림간의 싱크 문제에 대한 토의
http://www.codeproject.com/directx/rendering.asp

'Program > Direct Show' 카테고리의 다른 글

비디오 캡쳐 예제  (0) 2008.01.16
그래프 스파이 기능. AddGraphToROT  (0) 2008.01.16
VC - 1 이란  (0) 2008.01.16
:

그래프 스파이 기능. AddGraphToROT

Program/Direct Show 2008. 1. 16. 09:33
http://blog.naver.com/ryuee0516?Redirect=Log&logNo=30016721416
RemoveGraphFromROT
AddGraphToROT

소스 코드로 구성한 필터 그래프를 그래프 에디터에서 확인하기 위한 루틴..

'Program > Direct Show' 카테고리의 다른 글

비디오 캡쳐 예제  (0) 2008.01.16
Multimedia Streaming Synchronization Mechanisms Under DirectShow  (0) 2008.01.16
VC - 1 이란  (0) 2008.01.16
:

VC - 1 이란

Program/Direct Show 2008. 1. 16. 09:32
출 처 : bornlazybone
http://bornlazybone.tistory.com/2

멀티미디어
2007/09/08 23:57


이제 VC-1을 모르시는 분들은 별로 없겠지만, 혹시 모르시는 분들도 이름만 모를 뿐 실제로는 다 알고 계실 겁니다. 제가 '이름만 모른다' 란 표현을 쓴 이유는 VC-1이 바로 WMV9 이기 때문입니다.

이 글은 쓴 이유는 얼마전까지 이슈가된 MS 의 Open Office XML 논쟁을 보면서 WMV9이 VC-1 이란 이름을 달고 SMPTE 표준으로 선정된 수년전의 상황이 생각났기 때문입니다.

포스트 MPEG4 코덱 중 가장 대중적인 코덱은 H.264, WMV9, VP6/7 정도가 있습니다. 포스트 란 말을 쓴 이유는 이 코덱들이 MPEG4 가 나온 이후에 이를 개선하고자 고안되었기 때문입니다.

H.264 는 ISO 및 ITU-T 공동 결과물로서 MPEG4 Part 10 (ISO)또는 Advanced Video Coding (ITU) 이란 말로도 불립니다. VP6/7 은 미국 ON2 사의 코덱으로서 플래시 버전 8에 포함되면서(VP6.2) UCC 용 코덱으로 더욱 유명해 졌습니다. WMV9 은 따로 설명이 필요 없겠구요.

각 코덱마다도 빠(?) 들이 있습니다만, 저의 주관적 견해는 다른 포스트를 통해 밝히기로 하고, 여기서 각 코덱의 성능 비교를 하지는 않겠습니다.

각 코덱들이 서로의 활동영역을 넓히고 있을 때 쯤 MS 가 H.264 를 보면서 느낀 것은 비표준으로서의 설움이었던 것 같습니다.

성능 면에서 별 차이 없고(이거 논쟁거리 되는 발언입니다만), 중소사업자, 인터넷 방송이나 개인들은 엄청나게 사용해 주고 있는데, 대형 사업자 주도 또는 국가적 프로젝트에는 매번 제외되는 현실을 보았던 것입니다. 실제로는 무수한 레퍼런스가 있는 메이저이나 표준이 아닌 이유로 명분적 마이너가 되는 상황 말입니다.

우리나라의 DMB 방송의 비디오 코덱이 H.264 입니다. HD-DVD 도 H.264 가 유력했습니다. IPTV 를 하려는 각국의 사업자들은 표준이란 이유로 H.264 를 채택하려고 합니다. MS 의 입장에서는 코덱 전문가들 영입해서 뭔가 쓸만한 거 만들었다 싶었더니 푼돈만 만질 판입니다.

여기서 MS 가 떠올린 아이디어는 다름아닌 OOXML 과 같이 복수 표준으로 만들자는 거였습니다. 이미 H.264 는 ISO 표준인 관계로 MS는 SMPTE(Society of Motion Picture and Television Engineer) 란 조직에 작업을 하고 이들을 등에 업었습니다. 얼마의 시간이 지난 후(저는 얼마가 걸렸는지는 알지 못합니다만 아마도 파격적인 시간이 걸렸으리라는 것은 짐작됩니다) WMV9 은 VC-1 이란 이름의 SMPTE 표준으로 나타납니다.

VC-1 란 이름이 선택된 이유는 모르지만 WMV9(Windows Media Video9) 란 이름을 쓸 수 없었던 것은 분명합니다. 공개된 표준의 이름에 Windows 라니요… 하지만 MS 에서 약간의 미련은 남았었나 봅니다. VC-1 이란 이름 전에 잠시나마 VC-9 이란 이름이 사용되었으니깐요…

어쨌든 열심히 작업한 보람이 있어, VC-1 은 H.264 와 함께 HD-DVD 의 표준 코덱으로 선정되게 됩니다. DVD (MPEG2) 와 달리, HD-DVD 는 비디오 코덱에 있어 복수 표준을 가지게 된 것입니다.

VC-1 이 표준이 되고 난 다음 MS의 WMV9 에 대한 설명은 약간은 코미디 입니다. MS 에 의하면 WMV9는 이제 'Microsoft implementation of VC-1' 입니다. 갑자기 아들이 아버지가 되어버렸습니다 ㅋㅋ.

가끔 VC-1 을 WMV9 Advanced Profile 이라 알고 계시는 분들도 있는데, 이는 말만 무성했던 WMV9의 Advanced Profile 이 VC-1 을 통해서 공개되었기 때문입니다. 실제로 VC-1은 WMV 전제를 포함합니다.

MS 가 비디오 코딩에 대한 표준안 외에 함께 제출한 또다른 표준안이 있었는데, 이것은 VC-1 비디오를 MPEG2 Transport stream 에 실어 보내는 방법에 관한 것이었습니다.

이전까지 MS 가 WMV 를 위해 사용하고 있던 전송 포맷은 ASF 라는 형식이었습니다. 확장자 .asf 및 .wmv, .wma 같은 파일들이 ASF 포맷입니다. 하지만 ASF 를 표준화 하기에는 현실적 문제가 너무 많았습니다. 가장 큰 장애는 대부분의 디지털 방송 전송과 관련된 장비들이 MPEG2 의 TS(Transport Stream) 를 사용하고 있었다는 점이었습니다. 이에 고민하던 MS는 TS 에 VC-1 비디오를 담는 스펙을 함께 제출하게 됩니다.

VC-1 이 SMPTE 표준으로 선택된지 상당한 시간이 흘렀고, HD-DVD, 블루레이의 코덱으로 선택되는 등 많은 성과도 있었습니다.

하지만 세계는 넓고 먹어야할 시장은 아직도 많습니다. 아직도 갈길은 먼데 향후 VC-1 의 앞날이 밝지만은 않은 듯 합니다. 이에 대한 의견은 직전에 포스팅한 글로 대신해야 할 것 같습니다.
:

GExport

Program/파스칼 | 델파이 2008. 1. 16. 09:28

간단한 사용법과 홈페이지
http://www.gexperts.org

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls {$IFDEF DEBUG}, dBugIntf{$ENDIF};

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
nI : Integer;
begin

for nI := 0 to 1000 do
begin
{$IFDEF DEBUG}
SendDebugEx(intToStr(nI), mtInformation);
SendDebugEx(intToStr(nI), mtError);
SendDebugEx(intToStr(nI), mtWarning);
{$ENDIF}
end;

end;

: