초짜 플머 헬마 :: 'C++' 태그의 글 목록
Total : 566,481
'C++'에 해당되는 글 8건
2010.03.06 Visual Studio 2010 C++ 프로젝트 업그레이드 가이드 - From VC++ Team Blog - Part. II
2010.03.04 Visual Studio 2010 C++ 프로젝트 업그레이드 가이드 - From VC++ Team Blog - Part. I
2009.09.30 학교에서 또 한번 좌절... (4)
2009.07.16 C++ 용 사칙연산 계산기? (1)
2009.06.15 C++ - ANSI, UNICODE < - > UTF8 - 문자열 인코딩 변환 클래스 (4)
2009.06.11 로그 작성용 C++ 클래스
2009.04.27 코드는 보고 또 보고 !! 또 리뷰 하고! 꺼진불도 다시 보자! (1)
Visual Studio 2010 C++ 프로젝트 업그레이드 가이드 - From VC++ Team Blog - Part. II
프로그래밍/C++ 2010.03.06 22:16 |
이제 두번 째 글입니다. 총 3개의 글로 올라갈 것 같네요. 워낙 타자 속도가 느리니 이정도 글 번역하는데 며칠이 걸리는지 모르겠네요.
업그레이드 하는 동안 경고들
변환하는 동안 여러분이 겪을 수 있는 공통적인 경고들이 몇 개 있습니다.
1. 링커 출력 디렉토리
여러분이 어플리케이션을 업그레이드할 때 볼 경고중에 하나는 MSB8012: $(TargetPath) and Linker’s OutputFile property value does not match:
Link.OutputFile 은 등록정보의 링커 -> 일반 -> 출력 파일 에 선언된 값 입니다. 기본값으로 이 값은 $(TargetPath) 와 같은 $(OutDir)$(TargetName)$(TargetExt) 입니다. 그러나 이전버전에서 어플리케이션을 변환할 때 다른 고객들은 다른 방법으로 형식화된 값들을 가지고 있을 수 있기때문에 변환을 위해 $(TargetName) 과 $(TargetExt) 가 가르키는 정확한 값을 밝힐 수 있도록 Link.OutputFile 을 분석할 수 있는 쉬운 방법이 없습니다. 이 문제를 해결하기위해 우리는 변환을 하는동안 Linker.OutputFile 값을 보존하기로 결정했습니다. 변환후에 $(TargetName) 은 기본값으로 $(ProjectName) 으로 됩니다. $(TargetExt) 는 각 어플리케이션 형식에 맞는 기본값을 가질 것 입니다 : 동적 라이브러리 - .dll, 정적 라이브러리 - .lib, 어플리케이션 - .exe. Link.OutputFile 값은 그대로 보존될 것입니다. Link.OutputFile 과 $(TargetPath) 가 같지 않으면 변환 로그에 경고 MSB8012 가 발생할 것입니다. 여러분은 어플리케이션을 빌드할 때 같은 경고를 받게될 것 입니다.
$(OutDir), $(TargetName) 과 $(TargetExt) 는 "일반" 등록정보 페이지에서 "출력 디렉토리", "대상 이름", "대상 확장자" 로 확인할 수 있습니다. 여러분은 경고를 없애기위해 이 값들을 직접 수정할 수 있습니다.
- 만약 여러분의 프로젝트가 가져오기 라이브러리(Import Library) (Linker-> Advanced -> Import Library) 를 생성한다면, 링커 출력 디렉토리가 기본 출력 디렉토리가 아니면 변환후에 마찬가지로 가져오기 라이브러리의 출력 폴더를 변경해야합니다.
- 변환 후에 Debugging.Command 는 $(TargetPath) 로 설정됩니다. 여러분은 F5(Debugging) 또는 Ctrl + F5(Start Without debugging) 를 눌렀을 때 올바르게 실행되도록 변경해야할 수 있습니다.
2. 속성 시트 정렬
여러분의 어플리케이션이 속성 시트를 가지고 있다면 변환 후에 아래와 같은 문제점들이 발견할 수도 있습니다. :
- 사용자 매크로 선언전에 매크로들이 사용되는 구성 'Debug|Win32' 밑에서 발견되는 모든 사용자 매크로들은 의도치 않은 빌드 결과를 가져올 수 있습니다. 이번 배포버전에서 이러한 기능은 지원되지 않습니다. 이 문제는 사용자 매크로를 선언하는 속성 시트 다음에 매크로를 사용하는 속성 시트가 오도록 포함 순서를 변경함으로써 해결할 수 있습니다.
이 경고는 MSBuild 가 속성을 평가하는 방식때문입니다. MSBuild 는 순차적인 순서로 속성을 평가합니다. 상속받은 속성 시트에서 선언된 속성들은 속성들이 부모 속성 시트에서 사용됐다면 빈 값으로 평가됩니다. 그러나, VCBuild 는 속성들이 상속된 속성시트에서 선언되었더라도 부모 속성 시트의 속성들의 사용이 가능해지도록 지연평가를 합니다. 이 문제를 해결하려면, 경고메시지를 따라서 속성 시트의 포함 순서가 속성이 사용되기 이전에 선언되도록 변경합니다.
업그레이드 후 변경된 행동
우리는 기반 빌드 시스템의 변경에도 불구하고 고객들이 VS 2010으로 이전하면서 같은 경험을 갖도록 유지하기위해 노력했습니다. 다른 한편으로, 몇 가지 빌드 경험 향상시키거나 또는 MSBuild 만의 요구사항에 적응하도록 하기위해 변경을 가했습니다. 그 결과로, 여러분은 VS2010 으로 이전하면서 몇몇 달라진 동작들을 알아놔야합니다.
1. 솔루션 의존성 -> 프로젝트간 참조
이전 버전의 Visual Studio 에서 C++ 어플리케이션을 VS2010 으로 변환하면 솔루션 단계에서 선언한 프로젝트 의존성이 프로젝트간의 참조로 변환됩니다. 이러한 변경으로 인해 C++ 프로젝트 의존성을 프로젝트 파일에서 확인할 수 있습니다. 아래 사진은 프로젝트 파일에서 프로젝트간의 참조가 어떻게 나타나는지 보여줍니다 :
프로젝트 파일에 의존성 정보를 갖도록 하는 것은 여러가지 장점이 있습니다. 먼저, 사용자는 솔루션 없이도 프로젝트를 빌드할 수 있으며, 독립 프로젝트는 자동으로 빌드될 수 있습니다. 둘째, . 추가로, 많은 고객들은 다양한 솔루션 파일들은 가지고 있으며, 각 파일들은 다양한 프로젝트들의 하위모임입니다. 이러한 변경은 고객들이 각각의 솔루션 파일들에 대해 프로젝트 의존성 설정을 해야하는 일에서 해방시켜줍니다. 또 다른 중요한 사실은, 프로젝트간 참조를 통해서 설정되었을 때 빌드 의존성이 좀 더 안정적일 수 있습니다. 특히, 다중 코어를 사용해서 빌드할 때 그렇습니다. 이러한 일은 이전 버전의 Visual Studio 에서 발생했던 일입니다.
- 여러분이 C++ 어플리케이션에 의존하는 C# 어플리케이션을 가지고 있고 이러한 읜존성이 솔루션 의존성을 통해서만 표현된다면, 현재 변환 작업은 솔루션 의존성을 프로젝트간 참조로 변경하지 않습니다. 아마도 특히, MSBuild 를 명령행에서 직접 빌드 할 때 잘못된 빌드 순서로 인해 빌드 오류를 경험할 수 있습니다. 이 문제점을 수정하려면, 직접 C# 과 C++ 어플리케이션들에 대해 프로젝트간의 참조를 적절히 설정해야합니다.
- 일반적으로 VS2010 에서 빌드 의존성을 설정할 때 솔루션 의존성 대신 프로젝트간 참조를 사용하세요.
2. 프로젝트간 참조 속성 변경
변환 후에, CopyLocalDependencies 와 UseDependeciesInBuild 속성은 삭제됩니다. "Use in Build" 속성은 속성의 기능을 더욱 드러내도록 "Refernce Assembly Output" 으로 변경됩니다. 두 개의 속성 : "Link Library Dependencies" 와 "Use Library Dependency Inputs" 속성이 참조되는 프로젝트가 프로젝트의 출력을 참조하는 프로젝트에 넘길지 아닐지 제어할 수 있도록 하기위해 참조되는 프로젝트에 추가되었습니다. 아래 사진은 VS2008 과 VS2010 의 프로젝트간 참조 속성들의 비교사진입니다.
- 설정 "Reference Assembly Output" 를 "false" 로 하면, 프로젝트간 참조의 부분이 된 프로젝트가 참조하는 프로젝트의 CL 에게 프로젝트의 출력을 넘기지 않아도 빌드 의존성이 설정될 수 있도록 합니다. 이 속성은 관리되는 어플리케이션에서 사용됩니다.
- "Link Library Dependencies" 를 "false" 로 하면, 프로젝트간 참조의 부분이 된 프로젝트가 참조하는 프로젝트의 링커에게 프로젝트의 출력을 넘기지 않아도 빌드 의존성이 설정될 수 있도록 합니다.
3. VC++ 디렉토리 변경
VC++ 디렉토리는 더이상 도구 -> 옵션 페이지를 통해서 지원되지 않습니다. 대신, VS2010 은 전역 검색 경로를 포함하여 전역 설정을 제어하기 위해 사용자 설정 파일(Microsoft.cpp.<Platform>.users.props) 을 사용합니다. 이 파일들은 $(USERPROFILE)\appdata\local\microsoft\msbuild\v4.0 디렉토리에 있습니다. VS2010 으로 이전할 때 VS2005 또는 VS2008 의 VC++ 디렉토리의 사용자 설정들은 이 사용자 파일로 이전됩니다. 이 전역 설정파일등른 모든 변환되는 프로젝트와 새로 생성되는 프로젝트에 사용됩니다.
UI 를 통해서 설정을 변경하는 절차는 아래와 같습니다 :
- View.Property.Manager 를 클릭하여 속성 관리자를 엽니다.
- 프로젝트 항목을 확장해서 Configuration|Platform 선택하면 "Microsoft.cpp.<Platform>.users" 라는 파일을 각 Configuration|Platform 마다 확인할 수 있습니다. 이 파일들이 이전의 Tools/Options/VC++ 디렉토리와 유사하게 전역 설정을 담고 있습니다.
- "Microsoft.cpp<Platform>.users" 를 여러개 선택하여 오른쪽 버튼을 누르고 등록정보 페이지를 엽니다.
- 등록정보 페이지 창에 왼쪽 페인에서 "VC++ Directories" (예를 들어) 를 눌러서 "Include Directories" 와 같은 곳에 세미콜론으로 구분하여 새로운 경로를 추가합니다.
- Visual Studio 를 종료하기 전에 설정을 저장합니다.
- Visual Studio 를 새로 시작하면 새로운 설정이 적용됩니다.
알림 : 만약 어떤 프로젝트에 대한 설정만 변경하고 싶다면, 프로젝트에서 오른쪽 버튼을 눌러 속성 페이지를 불러올 수 있습니다. "VC++ Directories" 설정을 변경하면 이 설정들이 프로젝트 파일에 적용됩니다.
4. 사용자 빌드 규칙 변경
VS2008 에서 사용자 빌드 규칙은 .rules 파일에 선언되었습니다. 변환 작업은 .rules 파일들을 3 개의 분리된 파일로 변환합니다 : .targets, .xml, .props 파일입니다. 여러분은 변환후에 rules 파일들이 있던 디렉토리에서 이 파일들을 찾을 수 있습니다. 새로운 사용자 빌드 규칙을 추가할 수 있는 이용가능한 UI 는 없습니다.
5. 업데이트 점검 변경
여러분이 F5 를 누르면 아마도 방금 재빌드를 한 직후에도 언제나 점검 대화상자가 나타나는 상황을 겪었을 수도 있습니다. 이 문제를 해결하기위해 이 블로그를 참조할 수 있습니다. 어찌되었든, 이러한 문제가 나타난 원인은 프로젝트 파일의 일부분으로 되어있는 몇몇 파일들이 디스크에는 없었기 때문입니다. 왜냐하면, 이들 파일들은 프로젝트 파일들의 일부분이고 업데이트 점검 작동방식은 해당 파일들의 존재여부를 점검할 것 이기 떄문입니다. 만약 이 파일들이 디스크에 없으면 업데이트 점검은 새 빌드가 필요하다고 가정합니다. 해결방법은 만약 디스크에 파일들이 없으면 프로젝트 파일들에서 이 파일들을 삭제하는 것입니다.
우리가 VS2010 에서 가진 한가지 제한은 관리되는 증분 빌드를 지원하지 않는다는 것입니다. 우리는 미래의 배포버전에서 이 기능을 다시 가져오기위해 연구하고 있습니다.
Visual Studio 2010 RTM!!! (3)
프로그래밍/C++ 2010.03.04 21:34 |
학교에서 또 한번 좌절...
잡담 2009.09.30 11:27 |
오늘도 여전히 학교와 회사를 열심히(?) 다니고 있습니다. ^^
오늘은 오전에 -운영체제- ( 유닉스 운영체제 겠죠 ^^ ) 수업이었는데,
read, open 등의 함수를 설명하다가 실습 예제가 하나 나왔습니다.
main( argc, argv ) int argc; char* argv[];
int fd, skval;
fd = open( argv[1], O_RDONLY );
if( fd == - 1 )
printf("File FD Number = %d\n", fd );
while( ( skval = read( fd, &c, 1 ) == 1 )
printf("Read Char : %c\n", c );
skval = lseek( fd, 9L, 1 );
printf("New Seek Val = %d\n", skval );
위와 같은 프로그램이었는데 이걸 5글자씩 읽어서 출력하느걸로 고치는거였습니다. 그러면서 문자배열을 써보라더군요.
뭐 쉬운일이니 원하시는대로 했습니다.
char szData[6];
memet( szData, '\0', sizeof(szData) );
while( ( skval = read( fd, szData, 5 ) == 5 )
printf("Read Char : %s\n", szData );
memset( szData, '\0', sizeof(szData) );
로 고쳤습니다. 기억에 의존해서 정확한지 잘 모르겠네요.
컴파일도 잘 대고 깔끔하게 5글자씩 출력이 되었습니다.
그런데, 교수님께서 보시더니 왜 문자배열을 6개로 잡았느냐고 하면서 5개로 줄여보라고 하더군요.
그래서 5개로 줄이고 실행하니 당연히 널문자가 없어서 뒤에 쓰레기 문자가 잔뜩 같이 출력...
그러니 이번엔 교수님이 printf 에서 %5s 해서 길이 지정을 하면 되는거 아니냐고 해보라고 하더군요.
해보고 역시 안대죠. 교수님 %5s 는 최소 출력 길이 너비를 지정하는거지 읽는 길이를 지정하는게 아니란 말입니다. ㅠㅠ
printf 에는 읽을 길이 지정하는게 없냐고 하시더니 없다고 하니까 그냥 가시더군요.. ㅠㅠ
유닉스면 C언어와 굉장히 밀접한 운영체제인데, C언어를 제대로 해보신분인지 순간 놀랐습니다.
C언어에서 문자열이 어떤식으로 다뤄지는지 정말 알고계시는건지..
더구나 나중에 5개로 잡으면 찌거기 문자가 나올텐데 이건 정상작동이고 알고리즘 오류가 아니라고 주장하는 모습에 감동했씁니다
그대로 제품 만들면 100% 망할텐데...
벌집.... 구경하다... (6)
VMWare 7.0 Technology Preview Build. 185517 (1)
미디어법 통과를 보며 생각나는 장면... (1)
warship 2009.09.30 16:19 Address Modify/Delete Reply
printf("%.5s", szData);
점(.)을 찍으면 딱 5자리만 읽고,
printf("%.*s", 5, szData);
이것도 위와 같은 동작을....
저도 몰랐었는데 얼마전에 알았다는
헬마 2009.09.30 19:19 신고 Address Modify/Delete
MSDN을 찾아보았는데 일단 의미가 약간 다릅니다.
The third optional field of the format specification is the precision specification. It specifies a nonnegative decimal integer, preceded by a period (.), which specifies the number of characters to be printed, the number of decimal places, or the number of significant digits (see the How Precision Values Affect Type table). Unlike the width specification, the precision specification can cause either truncation of the output value or rounding of a floating-point value. If precision is specified as 0 and the value to be converted is 0, the result is no characters output, as shown below:
제가 판단하기로
위의 . 을 이용한 방식은, 읽기는 많이 있습니다. 쭉~~, 읽지만 출력은 딱 5글자만 합니다. 따라서, 겉으로 보기엔 5글자 이상을 초과해서 읽었다는 사실자체에는 변함이 없습니다.
차이점이라면, %5s 하면 최소 5글자로 그 이상 출력가능지만
%.5s 하면 무조건 5글자 출력이라는 거겠죠.
두번째 방법인 * 를 쓰는 방식은 현재는 거의 쓰이지 않는 방식으로 알고 있습니다. 추천되지도 않구요. 보안 위험성때문이지요. printf_s 같은 보안이 강화된 함수에서는 지원이 제거된걸로 알고 있습니다.
사실 머, 보안위험을 따지자면 printf 자체가 문제인거나 다름없죠 ^^
C++ 고유의 가변인자 전달 방법만 있었어도 printf 는 사라졌을거라 생각합니다.
blueasa 2009.10.01 02:48 Address Modify/Delete Reply
가끔씩 헬마님 글보면서 느끼는거지만..
교수랑 학생이랑 바뀐거 아닌가요? ㅇ_ㅇ;
neoevoke 2009.10.08 16:16 Address Modify/Delete Reply
교수님을 가르치시느라 고생하십니다 ^^
소스코드 올리실때는 textarea로 둘러싸 주시면 맨 밑에 </fncntl.h> 이런거 나오는거 없어져요
C++ 용 사칙연산 계산기?
프로그래밍/C++ 2009.07.16 14:24 |
얼마전부터 프로젝트에 사용할 사칙연산 계산기를 이리저리 찾아보다가 인터넷에서 적당한 넘을 하나 구했는데 기능이 많이 부족하더군요.
계산기 원소느는 구한지 몇개월이 지난거라 어디서 받았는지도 기억이 안나네요.. 원저자분이 누구셨는지 참으로 죄송합니다.
그래서 이리저리 뜯어보고 기능을 싸그리 고쳤습니다.
원 버전은 사칙연산, 연산자 우선순위, 괄호 지원까지 였는데 변수 라는 개념이나 기타 등등 도입해봤습니다.
그런데 만들어놓고 보니 코드가 좀 난잡해진거 같아서 코드 최적화랄까 기능 건의 라던가 필요할거 같아서 테스트 용으로 올려봅니다. ^^
1. 한번에 여러문장을 계산할 수 있으며 각 문장의 끝은 ; 로 구분하며, 이전문장에 변수에 값을 대입하면 다음 문장에서 그 변수의 값을 꺼내사용할 수 있습니다.
2. 변수의 값들은 Clear~ 함수를 사용하기전까지 유지됩니다.
3. 변수에 숫자의 벡터를 넣어 계산할 수 있습니다.
좀 더 빠르게, 최적화 방안이라던가, 기능 건의 있으면 댓글 달아주세요 ^^ 아직 만들다 만거라서 부족한 점이 많습니다.
int main( int argc, wchar_t* argv[] )
CCalculator ccalc;
// 값을 계산하여 a 라는 변수에 저장하고, 결과를 반환합니다.
vecVariables result = ccalc.GetResult( ccalc.GetPostfixExp( "a = 3*4 + (2+3);" ) );
// c 라는 변수를 계산기 내에 설정합니다.
vecVariables vecTemp;
vecTemp.push_back( 2.3 );
vecTemp.push_back( 3.3 );
ccalc.SetVariable( "c", vecTemp );
// 변수 a 와 c 를 더한 결과를 반환합니다.
result = ccalc.GetResult( ccalc.GetPostfixExp( "a + c;" ) );
Calc_Test.zip
Visual Studio 20081 SP1 통합... (0)
EmEditor 용 사전 플러그인??? (1)
C++ 용 사칙연산 계산기? (1)
Visual Studio 와 VMWare 원격 디버깅 - 2 - (2)
Visual Studio 와 VMWare 원격 디버깅 (1)
C++ - ANSI, UNICODE < - > UTF8 - 문자열 인코딩 변환 클래스 (4)
브레아 2009.07.17 21:33 신고 Address Modify/Delete Reply
헬마님~ 헬마님의 Winrar ++ 리팩버전 잘 이용하고있었는데, 요세 usb로 윈도우 다시깔기를 연습하면서
날려먹었는데, 헬마님 홈페이지에없어졋네요. 혹시 예전꺼 백업한거있으시면 보내주시면 고맙겠습니다.
메일 주소는 eroneko@naver.com 입니다.
C++ - ANSI, UNICODE < - > UTF8 - 문자열 인코딩 변환 클래스
프로그래밍/C++ 2009.06.15 02:13 |
이것도 이번에 프로젝트 중에 만든겁니다.
기능은 문자열간에 인코딩을 편하게 좀 바꿔보자가 만들었습니다.
내장 DB로 주로 SQLite 를 사용하거나, 또는 플렉스 라는 넘이 UTF8만 준다더군요.
그래서 UTF8 변환할 일이 좀 많아져서 만들었네요.
// ANSI, 또는 UNICODE 에서 UTF8 로 변환하기
std::string strText;
std::wstring strTextW;
CT2U8(strText).GetUTF8();
CT2U8(strTextW).GetUTF8();
// UTF8 에서 ANSI, UNICODE 로 변환
std::string strText8;
CU8T2(strText8).GetUTF16();
CU8T2(strText8).GetMBCS();
// GetUTF16 , GetMBCS 함수는 CT2U8, CU8T2 클래스 모두에 선언되어 있으니 편할 때 아무거나 선언해서 사용하시면 됩니다.
// 오히려 전 만들어놓고 보니 ANSI < - > UNICODE 변환에 더 많이 사용하게 되네요. ^^
ConvertUTF8.cpp
ConvertUTF8.h
Visual Studio 20081 HotFix (0)
로그 작성용 C++ 클래스 (0)
Visual Studio 2010 Beta 1 Team Suite - 설치편 - (1)
NCC 2009.07.01 10:46 Address Modify/Delete Reply
참고 하겠습니다. 좋은자료 감사합니다.
크키 2010.04.01 14:29 Address Modify/Delete Reply
굿!잡! 입니다.
^^ 잘쓰겠습니다.
ㅁㄴㅇㄹ 2012.08.23 20:47 Address Modify/Delete Reply
Util에서 isAlphabet가 잘못된 것 같네요.
for문을 돌릴때 isalpha() 이면 return true를 하는게 아니라
for문을 돌리는 와중에 !isalpha() 이면, 즉 캐릭터 하나라도 alpha가 아니면 return false를 하고 for문 바깥 마지막에 return true를 해야 std::wstring 또는 std::string 전체에 대한 isalpha 검사가 될 듯 싶습니다
a 2012.12.05 14:28 Address Modify/Delete Reply
1. DeletePtr, DeletePtrA 함수는 의미가 없습니다. delete나 delete[]연산 안에 이미 nullptr 검사 루틴이 있기 때문이고
2. 영문 윈도 등에서는 Korean_Korea 로캘을 찾지 못해 생성자에서 예외가 던져집니다.
3. 복사 생성자도 제대로 정의되어있지 않는 것은 물론이고, 문자열을 새로 대입할 때 다른 모든 멤버도 똑같이 초기화를 다시 해 주어야 합니다.
4. 심지어 UTF8에서 Ansi, Unicode로 변환하는 클래스는 제대로 짜여져있지도 않습니다.
5. isAlphabet 잘못된 건 윗 분이 지적해주셨으니 패스
혹시나 이 코드 가져다 쓰실 분들에게 참고가 되라고 남깁니다.
로그 작성용 C++ 클래스
프로그래밍/C++ 2009.06.11 20:25 |
오래만에 C++ 클래스 하나 올려봅니다. 사실은 Syntax 구문강조 기능 넣어서 적용되나 보려고.. ㄷㄷ
이번에 회사에서 프로젝트 하면서 간단하게 만들어본 로그 작석용 클래스 입니다.
정확히는 ACE 프레임워크에 있던 LOG 클래스 기능을 포팅했습니다.
ACE 프레임워크에서 로그 기능이 탐나는데 그거때문에 ACE 프레임워크를 쓰자니 뭔가 웃기는 짓거리 같아서 이것만 포팅했습니다.
구현은 싱글톤, 정적 클래스 로 구현되어 있습니다.
LM_INSTANCE()
위 매크로는 싱글턴 클래스의 포인터를 반환하여 로그 클래스를 조작할 수 있도록 해줍니다.
LM_DEBUG(( 내용 ));
위 매크로를 이용하여 로그를 작성합니다. 반드시 괄호를 2개를 사용하셔야 합니다. 내용에는 printf 처럼 몇가지 인자가 들어갈 수 있습니다.
예제).
LM_DEBUG(( _T("[%D %T][PID=%P][Thread=%t][%N-%l][ %s ]"), L"로그 클래스 시험" ));
위와 같이 작성하시면 %D = 날짜, %T = 시간, %P = 프로세스의 PID, %t = 해당 스레드의 TID, %N = 매크로를 호출한 소스코드 파일이름, %l = 매크로를 호출한 소스코드 행 번호, %s = 뒤에 적힌 문자열 로 치환됩니다.
LM_EXIT();
로그 클래스 사용이 끝나면 이 매크로를 추가하여 반드시 메모리에서 해제해야합니다. 그렇지 않으면 약간의 메모리 누수가 발생할 수 있습니다.
전체적인 예).
#include "Log_Msg.h"
std::wofstream ofStream( L"c:\\a.log", std::ios::out | std::ios::app );
ofStream->imbue( std::locale("kor") );  // 이 문장이 없으면 한글이 제대로 파일로 저장되지 않습니다.
// 로그를 파일 스트림과 디버그 출력으로 동시에 출력합니다
LM_INSTANCE()->Open( CLog::LOG_STREAM | CLog::LOG_DEBUGGER, &ofStream, false );
Visual Studio 2010 Beta 1 - X86, Team Suite - (0)
코드는 보고 또 보고 !! 또 리뷰 하고! 꺼진불도 다시 보자! (1)
코드는 보고 또 보고 !! 또 리뷰 하고! 꺼진불도 다시 보자!
프로그래밍/C++ 2009.04.27 22:23 |
오늘은 우연히 기존에 작성했던 라이브러리의 코드를 재구성하면서 다시 검토하게 되었습니다.
전에 이곳에도 잠깐 올렸던 코드인데요. - Http Web Post 클래스라고 해서 올린 적이 있습니다.
재구성하면서 보니 버그가 있네요. ㅠㅠ
코드는 깔끔하게 보시려면 여기서 보시면 되구요.
그냥 보시려면 글을 밑에 올립니다.
bool CHttpPost::AddItem(const std::string& strName, const std::vector<std::string>& vecData )
if( vecData.empty() )
for( std::vector<std::string>::const_iterator iter = vecData.begin(); iter != vecData.end(); ++iter )
DWORD dwPostData = strlen(iter->c_str()) * sizeof(wchar_t) + 1 * sizeof(wchar_t);
wchar_t *pszPostData = new wchar_t[ dwPostData ];
ZeroMemory(pszPostData, dwPostData);
int nPostResult = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, iter->c_str(), strlen(iter->c_str()), pszPostData, dwPostData);
dwPostData = strlen( strName.c_str() ) * sizeof(wchar_t) + 1 * sizeof(wchar_t);
wchar_t *pszName = new wchar_t[ dwPostData ];
ZeroMemory(pszName, dwPostData);
int nNameResult = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strName.c_str(), strlen(strName.c_str()), pszName, dwPostData);
if( nPostResult > 0 && nNameResult > 0 )
AddItem(tstring(pszName, nNameResult), tstring(pszPostData,nPostResult), true);
if( pszPostData )
delete [] pszPostData;
AddItem(strName, *iter, true);
코드를 보셨나요? 어느부분에 버그가 있을까요?
윈도 운영체제의 인코딩 변환함수인 MultiByteToWideChar 와 WideCharToMultiByte 함수는 은근히 사용하기 까다롭기로 유명합니다. 거기에 신경을 쓰다가 다른부분에 방심을 하고 말았네요.
윈도 운영체제의 인코딩 변환함수는 매개변수로 변환되서 저장될 공간을 직접 할당하고 그 크기를 알려줘야하는데요.
이게 두 함수가 살짝 달라서 헷갈리게 합니다.
하지만, 위의 코드는 버그는 거기에 있는게 아니었습니다.
잘 보시면 dwPostData 로 처음에 변환이 수행된 문자열이 저장될 공간을 할당하기 위해 크기를 계산합니다.
그리고 이 값을 그래도 new char 나 new wchar_t 에 사용하고 있는데요 . 사실 dwPostData 의 값은 바이트단위로 계산한 값이지
new 에 사용할 문자열의 갯수를 계산한 값이 아니라 최대 2배까지 공간이 더 할당되고 사용되지 않는 버그가 만들어지고 말았네요.
코드 자체가 작동하는데에는 문제가 없지만 이런 잠재적인 위험의 코드도 만들어서는 안되겠죠 ^^
오늘 코드를 옮기면서 새삼 깨닫고 말았네요. ^^
p.s strlen 등의 문자열 길이 함수는 널 문자를 제외한 길이를 반환해주기 때문에 이 길이를 토대로 new 로 할당할때는 널문자가 들어갈 공간만큼 (보통 1글자) 추가로 할당해줘야 합니다. 이를 까먹으면 문자열뒤에 이상한 글자가 연이어 붙어있는 짜증스런 상황을 겪게되죠 ^^
Visual Studio 2008 , 2월 ~ 3월 핫픽스 모음 (0)
SQLite 간단한 예제 프로젝트 (1)
푸른하마 2009.05.30 11:58 Address Modify/Delete Reply
봐두 모른다눈.