일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
김명신님의 "XAML 발음 XAML 읽기 : 제멀, 제므얼, 제믈"이 포스트를 보다가 예전에 있었던 에피소드들이 생각나서 끄적여 봅니다. 참고로 전 명신님의 포스트를 보기 전까지는 XAML을 그냥 엑스에이엠엘로 읽었답니다. ㅎㅎ 2002년인가 학교 선배가 IEEE를 구독하는 것을 알게되었습니다. 그전까지 저는 매번 IEEE를 아이이이이로 읽었죠. 읽기도 힘들고, 듣는 사람도 답답하고 그랬습니다. 한 날 선배가 그렇게 읽지 말고 아이트리플이로 읽으면 편하다고 가르쳐주더군요. 비슷한게 SQL이 있습니다. 전 그냥 에스큐엘이라고 읽었는데, 언젠가 관련 분야 종사자 분들을 만나니 전부 시퀄 시퀄 하시더군요. 첨에 뭔지 물어보지도 못했는데, 나중에 알고 보니 시퀄이 SQL을 읽는 것이더라고요. ㅋㅋ 2003년에는 더 재미난 것을 배웠습니다. 회사에서 키보드 보안 제품을 만들고 있었는데, 그 때 드라이버 쪽에 재미난 문제가 있었습니다. 키보드 인터럽트 후킹을 했는데, 훅 프로시저에서 iret을 호출하면 공포의 블루스크린을 보게 되는 것이었습니다. 고심하고 고심해도 문제가 해결되지 않았습니다. 물론 전 그때나 지금이나 드라이버 쪽 전문가는 아니라서 그냥 문제가 있다는 정도만 알고 있었죠. 그 때 개발팀을 이끌고 있던 팀장님께서 미국에서 열리는 WinHEC에 참석하고 오셨는데, 그 문제를 직접 인터럽트 전문가한테 물어봤다고 합니다. 그랬더니 그 전문가왈 "그건 니네 꺼가 아니기 때문에 후킹을 해서는 안된다. 다른 방법을 찾아라."라는 답변을 했다는 군요. 재미난건 그 다음입니다. 그 전까지 우리는 전부 iret을 아이알이티로 읽고 있었습니다. 내지는 인터럽트 리턴 정도. 그런데 그 팀장님께서 그러더군요. 미국 애들은 모두 붙이읽더라고 말이죠. 아이렛이라고 말입니다. 그나저나 그 팀장님 정말 멋지지 않나요? WinHEC가서 그런걸 직접 물어보시다뉘. ㅋㅋ XAML도 그런것 같은데, 의외로 AJAX도 읽는 분들마다 틀리게 읽더군요. 에이제이에이엑스, 에이잭스, 아작스, 아약스, ... 뭐가 답인지는 모르겠습니다. C++도 씨더블플러스라고 읽으시는 분도 있고, 씨뿔뿔이라고 읽으시는 분도 있죠. 찾아보면 재미난 것들이 더 있을것 같기도 하군요... |
낮에 라디오 듣는데 캐롤이 나오는게 이제 크리스마스도 얼마 남지 않았다는 생각이 들더군요. 오랜만에 캐롤 들으니 기분도 좋고, 설레기도 하고 그랬습니다... ㅎㅎ 그래서 몇 곡 퍼왔습니다. 즐감들 하세요... ^^;; 어렸을 때는 정말 크리스마스가 기다려졌는데, 지금은 그 때만큼 기다려지지는 않네요. 아마 선물 받기보다는 줘야하는 입장이 되서 그런게 아닐까 하는 생각을 해봅니다. 크리스마스에 진짜 산타클로스 할아버지가 있다면 어떤 선물을 받고 싶으세요? 전 딱히 생각해봐도 잘 떠오르지 않는군요. 세속에 너무 찌들었나 봅니다. ㅋ 나이가 든다는건 순수를 점점 잃어가는 과정이라고 말했던 어느 작가분이 생각나는 군요. |
![]() http://www.acornpub.co.kr/blog/175?TSSESSION=17d251dd1dbffa523dc955f92df6bebe 책 읽기를 좋아하시는 분들을 위해서 마이크로소프트웨서 문경수 기자님을 통해 알게된 "100 Books Club"을 소개해 드립니다. 대전에서 하는 독서 클럽인데 운영이 정말 제대로 되는 것 같습니다. 전 보자마자 가입했습니다. ㅎㅎ^^;; 대전이라 오프라인 모임은 참가가 힘들것 같지만 그냥 다른 분들의 독후감도 보고 올라온 추천 도서 목록만 보는 것으로도 가치가 있다고 생각했습니다. 사실 매번 이런 생각하지 않나요? 다음에 뭐 읽지? ㅋㅋ 그런 저의 질문에 좋은 길잡이가 될 것 같습니다. 더불어 문경수 기자님께서 추천해주신 책 두 권도 소개해 드릴께요. 전 아직 읽어보진 않았습니다. ㅎㅎ^^;; 재미있는 내용일것 같네요. 아마 그냥 제목만 봤다면 두 번째 책은 스킵했을것 같습니다. 엣지 재단을 운영하는 존 브룩만 아저씨가 출간한 책들입니다. 제가 위험한 생각들이란 책에 실망했다고 하니깐 추천해주시더라고요. 과학의 최전선에서 인문학을 만나다 우리는 어떻게 과학자가 되었는가 : 천재 과학자 27명의 호기심 많은 어린시절 세상은 넓고 읽을 것은 많은 것 같습니다. 하늘은 높고 또 배울건 많죠. 논어의 학이편 첫 구절이 생각나는 아침입니다. 學而時習之不亦說乎 有朋自遠方來不亦樂乎 |
윈도우 프로그래밍 테크닉 참을 수 없는 예외 처리의 편리함 신영진, codewiz@gmail.com, http://www.jiniya.net 윈도우는 오래 전부터 구조적 예외 처리(SEH, Structured Exception Handling)란 기법을 지원하고 있다. SEH의 사용법에 관해서는 이미 많은 책과 문서에서 소개했기 때문에 대부분의 개발자들이 그 사용법에 대해서 잘 알고 있다. 하지만 예외 처리 코드가 가지는 장점에 대해서 정확하게 이해하지 못해서 의외로 많은 개발자들이 실전에서 SEH나 C++의 예외처리 기능을 활용하지 못하고 있다. 이 글에서는 실패하지 않는 함수를 작성할 때에 SEH 코드가 가지는 장점에 대해서 설명한다. 우리가 오류나 예외란 상황에 접근하는 방법은 크게 두 가지다. 사전 처리와 사후 처리가 그것이다. 사전 처리란 어떠한 작업을 하기 전에 모든 조건이 완벽한지 검사를 하는 것이고, 사후 처리란 일단 작업을 하고 그것이 성공했는지 실패했는지를 살펴보는 것이다. 코드 상에서 사전 처리는 조건 검사를 의미하고 사후 처리는 예외 처리를 의미한다. 간단한 코드를 통해서 두 가지 접근 방법이 가지는 차이를 살펴보도록 하자. 리스트 1 출력용 포인터를 사용하는 함수 [CPP]void some_func(DWORD *some_ptr) { *some_ptr = 0x12345678; }[/CPP] <리스트 1>에 나타난 것과 같이 포인터를 인자로 받아서 값을 기록하는 간단한 함수를 생각해보자. 이 코드에서 발생할 수 있는 문제는 무엇일까? <리스트 1>의 코드가 당연해 보인다면 심각한 문제가 있다 리스트 2 ASSERT를 사용한 검사 [CPP]void some_func2(DWORD *some_ptr) { ASSERT(some_ptr != NULL); *some_ptr = 0x12345678; }[/CPP] 조금 숙련된 개발자라면 금방 <리스트 2>와 같은 코드를 생각해 낼 것이다. ASSERT는 실행 시간에 버그를 탐지하는데 굉장히 효율적인 방법이다. ASSERT 경고에 관한 활용에 대해서는 참고자료에 있는 “버그 안녕”이란 책을 살펴보도록 하자. some_func2는 안전해 보이지만 단지 개발단계에서 버그를 탐지할 수 있다는 가능성만을 포함하고 있다. 또한 Release 버전에서는 대부분 제거되도록 매크로를 작성해두기 때문에 배포 버전에서 발생하는 문제에 대해서는 점검을 하기가 쉽지 않다. 그래서 배포 버전에서도 절대 실패해서는 안 되는 함수에 대해서는 적합하지 않은 방법이다. 리스트 3 if문을 통한 검사 [CPP]void some_func3(DWORD *some_ptr) { if(!some_ptr) { SetLastError(ERROR_INVALID_ACCESS); return; } *some_ptr = 0x12345678; }[/CPP] 배포 버전의 안정성까지 생각한다면 <리스트 3>과 같은 코드를 생각해볼 수 있다. 단순히 NULL 체크를 해서 안전한 경우에만 값을 복사하는 것이다. “이제는 끝이겠지?”라고 생각하면 오산이다. 과연 some_ptr에 값을 기록하는 행동이 NULL인 경우를 제외하면 모두 안전할까라는 생각을 해보아야 한다. 현재 프로세스에 맵핑되지 않은 메모리 라던지, 읽기 전용 속성으로 맵핑된 메모리 일수도 있다. 그런 경우에도 여전히 함수는 실패한다. 리스트 4 IsBadWritePtr을 통한 검사 [CPP]void some_func4(DWORD *some_ptr) { if(IsBadWritePtr(some_ptr, sizeof(*some_ptr))) { SetLastError(ERROR_INVALID_ACCESS); return; } *some_ptr = 0x12345678; }[/CPP] 이쯤 되면 이제 윈도우 API를 동원할 때가 되었다. <리스트 4>의 코드는 IsBadWritePtr을 통해서 해당 메모리가 쓰기 가능한지를 체크하는 함수다. 해당 API의 구현은 뒤로하더라도 이 정도면 some_ptr에 대한 기록을 하는 행동은 안전하다고 할 수 있다. 이 간단한 작업에도 이렇게 생각할 것이 많은 것이다. 리스트 5 SEH를 사용한 코드 [CPP]void some_func5(DWORD *some_ptr) { __try { *some_ptr = 0x12345678; } __except(EXCEPTION_EXECUTE_HANDLER) { SetLastError(ERROR_INVALID_ACCESS); } }[/CPP] <리스트 4>와 동일한 코드를 SEH로 작성한 것이 <리스트 5>의 코드다. 간단한 코드이기 때문에 코드만으로는 예외처리의 장점을 알기가 쉽지 않다. 단지 명확한 한 가지 단점은 복잡한 조건을 미리 생각하지 않아도 된다는 점이다. __try, __except 블록으로 인해 너무 복잡해 보인다거나, 예외처리 때문에 늦어진다고 불평을 할 수 있다. 하지만 이는 예외 처리에 대한 메커니즘을 정확하게 이해하지 못해서 발생하는 오류다. 우선 __try, __except 블록에 대해서 살펴보자. 분명히 <리스트 4>에는 그러한 것이 없다. 하지만 진짜 없는 것은 아니다. IsBadWritePtr이란 함수 속에 그 블록이 숨겨져 있을 뿐이다. 그렇다면 성능은 어떨까? <리스트 4>의 코드는 오류가 있건 없건 항상 IsBadWritePtr을 호출한다. 반면에 <리스트 5>의 코드는 그런 사전 검사에 드는 비용이 없다. 예외가 발생했을 때만 예외처리 코드가 수행된다. 따라서 <리스트 5>의 코드가 더 효율적이다. 복잡한 사전 조건을 모두 검사할 필요가 없다. 조건 검사 코드가 매번 실행되지 않기 때문에 효율적이다. 정상 코드와 예외 처리 코드가 분리되기 때문에 코드의 가독성이 증가한다. 개발자가 상상도 못했던 진짜 예외가 발생한 경우에도 대처할 수 있다. 큰 것만 생각해도 예외 처리가 가지는 장점은 이렇게 많다. 따라서 복잡한 조건 검사보다는 명확한 예외처리를 사용하는 것이 좋겠다. SEH와 CRT 생각보다 많은 컴파일러 기능들이 CRT와 연결되어 있다. C++ 예외뿐만 아니라 SEH 또한 CRT 없이는 컴파일을 할 수가 없다. 예외 처리가 포함된 코드를 포함해서 컴파일을 하려고 하면 __except_handler3을 링크할 수 없다는 에러가 난다. Visual Studio에 번들 된 CRT 소스에도 이 함수는 포함되어 있지 않다. 그래서 자칫하면 CRT 없이는 예외처리를 사용할 수 없다고 생각하기 쉽다. 하지만 이는 진실이 아니다. 참고 자료에 있는 Matt Pietrek의 글을 읽으면 알 수 있겠지만 SEH는 근본적으로는 CRT와 상관이 없는 운영체제 기능이다. 컴파일러에서 CRT를 요구하는 이유는 컴파일러가 생성하는 코드에서 사용하는 SEH 필터 함수가 CRT에 포함되어 있기 때문이다. 이 문제를 해결하는 방법으로는 크게 세 가지 정도가 있다. DDK에 포함된 exsup.lib, sehupd.lib을 이용하는 방법, 경량 CRT 라이브러리인 tinycrt를 사용하는 방법, SEH 코드를 직접 구현해서 사용하는 방법이 그것이다. 참고자료 “버그 안녕! (Writing Solid Code)” 나윤석 옮김, 높이깊이 “Programming Applications for Windows (4/E)” Jeffrey Richter, Microsoft Press SEH 사용법 http://serious-code.net/moin.cgi/SEH A Crash Course on the Depths of Win32™ Structured Exception Handling http://www.microsoft.com/msj/0197/exception/exception.aspx |
요즈음 간단한 드라이버를 만들 일이 있어서 소스 인사이트를 설치했습니다. 뭐 드라이버를 꼭 소스 인사이트로 개발해야 되는 것은 아니지만 제가 처음 드라이버란 것을 알게된 회사에서 대부분의 드라이버 개발자 분들이 소스 인사이트를 사용했기에 은연중에 소스 인사이트로 개발하면 편리하다는 생각을 하게 되었습니다. 그 많은 개발자들이 쓰는데는 이유가 있다고 생각했거든요. ㅋ 그러고 보면 참 첫 경험은 정말 중요합니다. 누군가 노트패드로 드라이버 개발하는 것을 봤으면 저 또한 그렇게 할지도 모르는 일이니까요. ㅋ 하여튼 설치하고 업데이트 받고 했습니다. 그리곤 DDK 경로를 설정하고 심볼 패스에 추가하고 *드디어* 실제 드라이버 프로젝트를 생성했습니다. 으례 그렇듯이 DriverEntry를 코딩합니다. 심벌이 제대로 설정됐나 보기 위해서 PDRIVER_OBJECT에서 커서를 놓아봅니다. 오오 좋습니다. ㅋ 옆에 PUNICODE_STRING으로 이동합니다. 그런데 이놈 PUNICODE_STRING을 찾지를 못합니다. 쌩 쑈 끝에 원인을 알아 내었습니다. ntdef.h에 정의된 PUNICODE_STRING 정의 위쪽 어느 부분 부터 파싱을 못하더군요. ![]() 문제를 단순화 시키면 위와 같습니다. 똑같은 두 문장이 반복되서 나오는데 첫 번째 A_FOO를 보면 진하게 표시된게 소스 인사이트가 알아 먹었음을 알 수있습니다. 그런데 두 번째 A_FOO를 보면 연하게 표시된게 소스 인사이트가 알아먹지 못했음을 알 수 있습니다. 헐헐. 뭔가 파서의 문제라는게 확 느껴지지 않나요. 삽질한게 아까워서 감히 염치도 없이 소스 인사이트 서포트 메일에 버그인 것 같다고 메일을 보냈습니다. 그리고는 Visual Studio를 꺼내서 ddkbuild로 작업했습니다. 소스 인사이트 뽀대가 좀 아쉽긴 했습니다. ㅋ 오늘 답장이 왔습니다. 아래 부분이 메일의 핵심입니다. The problem can be handled by using the Edit Condition dialog, and defining the state of DEFA. You can find information here:간단하게 해결책을 설명드리면 파싱하지 못하는 곳의 #if, #ifdef, #ifndef 등에 사용된 조건 변수를 지정해 주라는 것입니다. 위의 그림에서는 두번째 A_FOO가 시작되는 #ifdef ABC 부분에서 ABC를 선택하고 오른쪽 마우스 버튼을 누르면 메뉴가 나오죠. 거기서 Edit Condition을 선택합니다. 그리고 ABC를 0으로 설정해 줍니다. 그럼 제대로 파싱이 된답니다. 그런데 이걸 일일히 찾아서 해주기엔 너무 귀찮잖아요. ㅋㅋ 그래도 소스 인사이트 뽀대를 쓰기 위해서 ddk 헤더를 열어서 저 뻘짓을 해줬습니다. 물론 심벌 못보고 코딩해도 별 상관은 없지만 좀 아쉽잖아요. 소스 인사이트 쓰는게 그것 때문인데. ^^;; ![]() |
![]() 데스크탑으로 작업을 많이 안하다보니 바탕화면이 이렇게 되버렸습니다. 그 때 그 때 다운받아 놓고 지우지 않은 탓이죠. 어제 보면서 머리가 너무 아파서 정리 좀 해야 겠다는 생각이 들더군요. 그래서 필요 없는 것들은 지우고, 필요한 것들은 옮기고 정리를 좀 했습니다. ㅋ 아래는 정리하고 나서 찍은 화면입니다. 깔끔해졌죠. 원래는 ObjectDock이란 프로그램을 사용해서 빠른 실행(Quick Launch)를 거의 쓰지 않았는데 의외로 ObjectDock이 UI만 화려하고 불편해서 지워버렸습니다. ![]() 처음에 데탑 살 때는 64비트 환경을 공부해보고자 질렀는데, 지금은 거의 스타 리그 플레이어가 된 것 같아서 좀 씁쓸하더군요. 앞으로는 공부하는데 더 많이 사용해야 겠습니다. 저는 24인치 와이드 모니터를 사용하는데 해상도가 1920x??입니다. 그러다보니 가장 안쓰게 되는 윈도우 버튼이 최대화 버튼이 되었습니다. 최대화 시키면 창이 한 눈에 들어오지 않죠. 늘 어정쩡한 크기의 창을 몇 개 띄워놓고 사용하다 보니 화면을 제대로 쓰는 경우가 거의 없습니다. 단지 큰 화면에서 중간 특정 지점만 사용하는 형태죠. 다른 분들은 어떻게 사용하시는지 모르겠네요. 와이드 모니터 제대로 사용할만한 방법이 없을까요? 윈도우를 쓸 때 또 한 가지 불편한 점은 제가 원하는 창을 찾기가 쉬운 일이 아니란 점 입니다. 저는 작업하다 보면 탐색기가 엄청 나게 늘어나는 특징이 있습니다. 컴파일된 바이너리가 생기는 폴더가 주로 너저분하게 늘어나죠. 나중에 다시 쓰기 때문에 잘 닫지 않는답니다. 그럴 때 열어둔 창 중에서 제가 원하는 창을 찾기란 여간 어려운게 아닙니다. 몇 개 안될 때는 머릿속에 위치로 기억을 해두기 때문에 쉽게 찾을 수 있지만 열 개가 넘어가면 그렇게 되지 않죠. 저만 그런지도 모르겠네용 ㅋㅋ 끌으로 노트북과 데스크탑을 사용하면서 느낀 불편한 점은 두 컴퓨터간의 동기화가 되지 않는다는 문제 입니다. 노트북에서 작업하던 소스를 데스크탑으로 옮기려면 일일히 수동으로 옮겨줘야 하죠. 정말 불편한게 이만저만한게 아닙니다. 홈페이지 서버에 SVN에 돌아간다면 얼마나 좋을까하고 생각한게 한 두번이 아니죠. 마땅하게 SVN을 지원해주는 호스팅 업체를 찾기도 쉽지 않더군요. 그래서 매번 울며 겨자먹기로 파일을 일일히 압축해서 메일로 보내거나 FTP에 올려두고 다시 다운받는 답니다. SVN을 지원하는 호스팅 업체나 다른 좋은 방법을 알고 계시다면 좀 알려주세용. 물론 소스 코드 동기화는 동기화 문제 중에 아주 일부분입니다. 설치된 프로그램 이라던가, 빠른 실행 아이콘의 배치, 즐겨 찾기 내용, Visual Studio 설정 등등 동기화 시키고 싶은 것들이 너무 많습니다. ㅎㅎ 의외로 불편한 점이 많았네요. ㅋㅋ 다른 분들은 어떤 점이 불편한지도 궁금하군요. ^^;; |
다소 낚시성 제목일 수도 있겠습니다. 지난 주에 window31님 블로그를 보다가 POC란 행사에 대해서 알게 되었습니다. '그런것도 모르고 보안 업체에서 밥벌어 먹다뉘'라고 말씀하신다면 할말이 없습니다. 하여튼 관련 소식을 꽤나 자세하게 적어주셔서 어떤 강의 내용이 진행되었는지 개략적으로나마 알 수 있게 되었습니다. 첫 날 후기를 보면 Immunity Debugger라는게 나옵니다. 또한 그 내용에 window31님이 가장 관심을 가졌다니 더욱 관심이 가더군요. 그런데 전 그 글을 읽기 전까지 Immunity Debugger가 뭔지도 몰랐습니다. 점점 부끄러워지는군요. ㅠㅠ 그래서 구글을 검색해 봤습니다. 그랬더니 그 디버거를 만든 회사 홈페이지가 뜨더군요. 아래 페이지에서 디버거의 소개를 보실 수 있고 다운로드도 받을 수 있습니다. 무료입니다. http://www.immunityinc.com/products-immdbg.shtml 소개글도 영어고, 화면은 대충보니 ollydbg랑 비슷해 보입니다. 일단 다운로드를 받고 설치를 하고 실행을 시켰죠. 그리곤 실행 파일 하나를 올려놓고 디버거를 수행해 봤습니다. 완전 ollydbg 붕어빵입니다. UI며 커맨드며, 뜨는 메뉴까지, 헐... 그리곤 왜 똑같은 놈을 만들었을까란 생각을 잠시했습니다. 물론 ollydbg보단 뭔가 정돈된 느낌이 들긴 했습니다. 툴바 아이콘이 조금 그랬습니다. 도움말을 열어봤습니다. 그것도 ollydbg 붕어빵이더군요. 디버거를 끄고는 회사 홈페이지를 좀 탐험했습니다. "August 10, 2007: Damian Gomez - Intelligent Debugging"이런 좋은 문서가 있더군요. 물론 읽지는 않고 쭉쭉 넘겼습니다. 그냥 대충 글에서 보이는 느낌이 파이썬으로 뭔가를 할 수 있다. 이런 것을 전하고 있다는 것을 알 수 있었습니다. 그 느낌은 맞았습니다. 그것도 정말 토할것 같은 기능이더군요. 보통 IsDebuggerPresent 함수로 디버깅 중이면 프로그램을 종료하거나 익셉션을 발생 시키는 놈들을 디버깅 할 때, IsDebuggerPresent 함수를 패치하거나 그 함수를 호출하는 부분을 패치시키고 디버깅을 합니다. 후훗. 그걸 Immunity Debugger로 어떻게 하는지 한 번 살펴볼까요? 파이썬입니다. 아래 코드가 그것이죠. [PY]import immlib def main(args): imm = immlib.Debugger() idp = imm.getAddress("kernel32.IsDebuggerPresent") imm.writeMemory(idp, imm.Assemble("xor eax, eax\n ret"))[/PY] 저걸 실행하는 방법은 간단합니다. 위의 코드를 Immunity Debugger가 설치된 폴더에 있는 PyCommands 폴더에 passidp.py로 저장합니다. 그리고 Immunity Debugger에서 실행 파일을 열고 밑에 커맨드 창에 !passidp라고 치면 IsDebuggerPresent 함수가 무력화 됩니다. 정말 디버깅이 아트가 되는 순간이 아니겠습니까? 이럴때는 정말 마음껏 토해줘야 합니다. 현기증 날 정도로 아찔하더군요. "어떻게 저 따위로 돌아가게 만들어 놨을까? 파이썬으로 저런 짓을 할 생각을 했을까?"란 생각을 한참을 했습니다. 그리곤 결론을 내렸습니다. 걔네는 천재임에 틀림없다고 말이죠. 적어도 저에게는 그랬습니다. 그들의 참신함은 거기가 끝이 아닙니다. 메뉴를 보면 마지막 풀다운 메뉴가 Jobs 입니다. 기부를 어떻게 하는지 사람을 뽑고 있는지, 인턴쉽 기회가 있는지에 대한 메뉴더군요. 아마 이 툴을 써본 많은 디버거들에게 꼭 들어가고 싶은 회사로 찜하지 않을까하는 생각을 해봤습니다. 물론 요즘 이스트소프트도 이런 식의 구인 광고를 많이 하더군요. 이 글을 읽고 난다면 아마 느끼실 겁니다. 아, 파이썬 배워야 겠군나. 그렇습니다. 파이썬은 이제 선택 언어가 아니라 필수 언어가 되었습니다. 파이썬을 아는 개발자, 그렇지 않은 개발자로 나뉠지도 모르겠다는 생각을 해봅니다. 파이썬을 배우고 싶으시다면 아래 튜토리얼을 참고하세요. 왠만한 파이썬 책보다 괜찮은 것 같습니다. 사실 책입니다. ㅋ http://www.diveintopython.org/toc/index.html |
지난 주말에 마소 원고를 썼어야 했는데 소리통 기능 추가한다고 뻘짓좀 하고, K가 면접 있다고 올라와서 좀 놀아주고 하다보니 몇 페이지 쓰지도 못하는 초유의 사태가 발생했습니다. 원고 마감이 몇 일 남지도 않았기 때문입니다. 그래서 요 몇 일 좀 바빴습니다. 맨날 미루다가 된통 당했네용. ㅎㅎ 하여튼 그런 우여곡절 끝에 Matilda1 바이러스가 만들어졌습니다. ㅋㅋ 첨에 당연히 C++로 만들어야지 하고 만들기 시작했는데, 중간에 포기하고 어셈블리로 만들뻔 했습니다. 하지만 뛰어난 끈기와 투지로 함정을 헤쳐나가서 마침내 C++로 PE를 감염시키는 아주 정직한 바이러스를 만들었습니다. 어떤 바이러스인지 궁금하시죠? 감염된 파일을 실행하면 아래 화면처럼 마우스 포인터가 위치한 곳에 Matilda1이란 글자를 마구 씁니다. 증상은 그게 답니다. 프로그램 종료할 때까지 열심히 쓰죠. 증상은 그게 전부입니다. 뭔가 그럴싸한 증상을 만들고 싶었으나 마땅한게 없더군요. 근사한건 너무 길어서 ㅋㅋ ![]() 감염된 파일이 실행되면 c:\test 아래에 있는 실행 파일 중에 감염되지 않은 놈을 전염시킵니다. 전염 시킨 놈을 디버그 출력으로 찍어주죠. 아래는 그렇게 전염되는 것을 캡쳐한 화면 입니다. ![]() 아래는 Matilda1의 바이러스 코드 진입점입니다. 이 부분만 보고 이게 무슨 C++ 이냐고 하실 수도 있지만 나머지는 다 C++입니다. ㅋㅋ 물론 인라인 어셈블리가 종종 등장하긴 합니다. [CPP]__declspec(naked) void Entry() { __asm { jmp $start _emit 'M' _emit 'a' _emit 't' _emit 'i' _emit 'l' _emit 'd' _emit 'a' _emit '1' $start: mov eax, [esp] push eax call FindPEHeader test eax, eax jz $oep push eax call InitTrampolines call Matilda1 $oep: push OriginalEntry ret } }[/CPP] Matilda1에 감염되면 파일의 끝에 .vmat 섹션이 추가되고 엔트리 포인트가 바이러스 코드로 변경됩니다. 따라서 휴리스틱 기능을 사용하는 백신 엔진에는 바로 걸리겠죠. 결국 마소 12월호 광고 였습니다. ![]() 소리통에도 근사한 기능 추가가 임박했습니다. ShoutCAST 관련 버그 패치, UI 기능 추가, 환경 설정, 라디오 청취 기능이 추가될 계획입니다. ㅋㅋ |
그동안 짬짬이 모인 강컴 마일리지가 꽤 되어서 책 두 권을 질렀습니다. 물론 제 돈도 쬐끔 보탰죠. 몇 년 만에 사는 컴퓨터 책인지 모르겠네요. 딱딱한 책이 싫어서 조금 피하고 있었습니다. ㅋ 지른 두 권의 책은 "C++ 표준 라이브러리 확장", "Windows 시스템 프로그래밍 3/e"입니다.
이 글을 쓰다가 알게된 사실인데 boost가 세벌식 자판에서는 추천이란 단어로 입력된답니다. 뭔가 신기하지 않나요. boost는 추천 라이브러리 입니다. 참고로 C++ 표준 라이브러리에 대한 책으론는 "C++ Standard Library 튜토리얼·레퍼런스"가 괜찮습니다. 레퍼런스로 적격인 책이죠.
류광표 번역이란 말이 있습니다. 류광님 번역의 질이 높고, 좋은 책들만 엄선해서 번역하기 때문에 생긴 말이라 생각됩니다. 번역하신 책이 정말 많은데 다들 주옥같은 책들이더군요. 번역이란 직업을 떠나서 자신이 하고 있는 일에 대해서 다른 사람들에게 그만한 무한 신뢰를 줄 수 있다는 사실이 정말 대단하다는 생각이 듭니다. 한번도 실망시키지 않은 류광 님의 책으로 또 열공하러 가야겠습니다. 책 이야기가 나온 김에 좋은 책 소개를 해주는 강추할만한 블로그 두 곳을 소개합니다. 제가 읽는 책의 상당수는 이 블로그에서 보고 사서 읽는 경우가 많습니다. *^^* Toivoa.com - Last Paromix - 끝으로 많은 윈도우 개발자들이 애타게 기다리고 있을 Jeffrey Richter의 신작 "Windows via C++"을 소개하면서 마칩니다. Jeffrey Richter 아저씨 블로그를 보니 이제 XXX via YYY란 책 제목에 재미 들인것 같더군요. 깔끔하고 좋은것 같아요. 이 책을 류광님이 번역해 주신다면 진짜 금상첨화겠죠. ![]() |
오늘 친구 녀석이 Notepad++에서 CSS 파일이 안열린다고 하더군요. 그래서 해보니 진짜 CSS 파일이 열리지 않았습니다. 디버깅을 해보니 CSS 파일을 파싱하는 함수에서 사용한 isalnum에서 오류가 발생하더군요. isalnum은 영문이나 숫자인 경우에 0이 아닌 값을 반환하는 함수입니다. 로케일이 잘못 설정되어 있을때 한글을 이 함수에다 집어 넣으면 오동작을 한답니다. 콘솔 프로그램을 만든 다음 아래 코드를 컴파일해서 실행하면 ASSERT 경고가 뜨는 것을 볼 수 있을 겁니다. [CPP]char *str = "안녕하세요"; isalnum(str[0]);[/CPP] 따라서 한글을 사용하기 위해서는 반드시 로케일을 적절하게 설정해 주어야 합니다. 아래와 같이 수정을 하면 오류가 뜨지 않는 것을 볼 수 있습니다. setlocale 함수는 CRT 로케일 설정을 변경하는 함수로 프로그램 시작 시에 한번만 설정해주면 됩니다. [CPP]setlocale(LC_ALL, ""); char *str = "안녕하세요"; isalnum(str[0]);[/CPP] Notepad2 2.0.18 버전은 새로 컴파일한 실행 파일을 사용하시면 됩니다. Notepad++은 실행 파일 폴더에 SciLexer.dll을 덮어쓰면 됩니다. |
오늘 출근하니 세 번째 구글 수표가 도착해 있네요. 금액은 늘 비슷한 140 달러네용. 고맙게 쓰도록 하겠습니다. ㅋ 애드센스 팀에서 메일이 한 통 왔습니다. 이름하여 애드센스 최적화 종합 가이드 같은 거더군요. 매번 기계식 최적화 보고서만 받다가 저런거 보내주니 기분이 좋았습니다. 만든다고 꽤나 고생했을것 같은데, 도움이 될 것 같습니다. ![]() 친한 학교 선배가 이번에 구글 코리아에 입사했습니다. 여차 저차해서 구글 이야기를 들을 기회가 좀 있었는데, 정말 개발자에겐 천국같은 회사더군요. 이래저래 저에게 도움을 많이 주고 있는 구글 이야기였습니다. ㅋㅋㅋ |
![]() okto님께서 줄번호가 크게 표시된다고 해서 Notepad2를 한번 살펴보았습니다. 그랬더니 글꼴을 크게 해도 줄 번호는 크기가 바뀌지 않더군요. 이 말이 즉슨, 줄 번호를 위한 별도의 폰트를 가지고 있다는 말이 되겠죠. 그래서 소스를 살펴보았더니 역시나 줄 번호는 다른 폰트로 그리더군요. 그렇다면 줄번호 폰트는 어디서 설정하느냐? 하는 질문이 생길 텐데요. 도구의 테마 바꾸기 메뉴에서 변경할 수 있습니다. 거기서 Default Text를 선택하면 Margins and Line Numbers가 나오죠. 그곳의 지정해 둔 폰트로 줄 번호를 그려 집니다. ![]() |
전 작업 표시줄을 세 줄로 사용합니다. 노트북이라 보통은 자동 숨김 옵션을 켜두고 사용하죠. 그래서 평소 때 작업할 때는 아래와 같은 화면이 연출되곤 합니다. 물론 아래 화면은 보여주기 위해서 무작위로 탐색기와 익스플로러를 많이 띄운 것입니다. 보통 때는 각기 다른 창들로 저만큼의 공간을 차지 한다는 것이죠.![]() 얼마전에 우연찮은 기회에 노트북 메모리를 업그레이드 할 수 있었습니다. 원래 1GB였는데, 업그레이드해서 2.5GB가 되었죠. 업그레이드하면서 스왑이 좀 줄겠군 이라고 생각했습니다. 역시 생각대로 덜 버벅대더군요. 그런데 웃긴게 예전에는 한 번도 보지 못했던 메모리 부족으로 프로그램을 실행할 수 없다는 메시지를 몇 번 보게 되었습니다. 어제 오늘 한 5~6회 만난것 같네요. 처음엔 바이러슨가 하고 생각하다가, 창을 닫으면 다시 실행되길래 그건 아닌가보다고 생각을 했습니다. 그리곤 작업관리자를 띄워서 확인해 봅니다. 늘 상 할당된 메모리가 1.2 ~ 1.4GB 사이더군요. 이렇게 메모리가 많이 남았는데 왠 메모리가 부족하다는 말이 나올까 궁금했습니다. 프로그램을 한 번 만들어봤습니다. 과연 이 녀석이 2GB를 쓰긴 할까 하는 생각으로 말이죠. 할당만 마구마구 하는 프로그램을 만드니 금새 2GB까지 사용하더군요. 그 상태에서 다른 프로그램들을 띄워 보았습니다. 메모리가 없는데도 잘 뜹니다. 당연하겠죠. 스왑이 있으니까요. 그럼 제가 아까 본 메모리 부족 오류는 무엇일까요? 그 다음 추측은 GDI 객체 였습니다. 창을 많이 띄우면 GDI 객체도 늘어나고 그것 때문에 창이 생성이 되지 않을 것이라는 추측을 한 것이죠. 그래서 작업 표시줄을 띄워놓고 좀 테스트를 해봤습니다. 그랬더니 정말 GDI 객체랑 연관이 있어 보였습니다. ![]() 그런데 제가 이제껏 알기론 NT 계열 운영체제에서는 GDI 객체의 경우 메모리가 허용하는 한도 내에서 생성이 되는 걸로 알고 있었습니다. 그게 상식에 부합하잖아요. 앞서 만들었던 프로그램을 수정해서 GDI 객체를 무작위로 생성하도록 만들었습니다. 10000개 가까이 되니 더 이상 생성을 못하더군요. 이상했습니다. 메모리는 넘쳐나는 상황이었거든요. 구글에 물어보니 역쉬나 레이몬드 첸 아저씨가 친절하게 답변을 해주시는 군요. http://blogs.msdn.com/oldnewthing/archive/2007/07/18/3926581.aspx 하지만 이건 앞서 생각했던 근본에 대한 답변은 아니죠. 프로세스 당 제한이니까요. GDI 객체를 생성하던 놈이 9000개 정도 생성한 다음 다른 프로그램을 실행하면 잘 됩니다. 그렇다면 도대체 그 메모리 에러는 왜 난 것일까요? 답은 아래 페이지에 나와 있습니다. 2.5GB의 메모리를 장착하고도 데스크탑 힙이 3MB로 한정되 있어서 메모리가 부족하다는 오류를 만난 것이었습니다. 8MB로 늘려 주었습니다. 이제는 더 이상 메모리가 부족해서 창을 생성할 수 없다는 오류 메시지를 만나지 않겠죠. ㅋㅋㅋ http://www.techarp.com/showarticle.aspx?artno=238 http://weblogs.asp.net/kdente/archive/2004/06/04/148145.aspx http://support.microsoft.com/default.aspx?scid=kb;EN-US;q126962 http://monac.egloos.com/1396478 http://www.blogcastrepository.com/blogs/mattbro/archive/2006/08/21/2013.aspx http://support.microsoft.com/default.aspx?scid=kb;EN-US;184802 http://www.techarp.com/showarticle.aspx?artno=238&pgno=1 http://msdn2.microsoft.com/en-us/library/ms724291.aspx 데스크탑 힙을 늘리는 방법은 간단합니다. 레지스트리 에디터에서 "HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -> Control -> Session Manager -> SubSystems"를 엽니다. 거기서 Windows 항목을 선택합니다. 그럼 아래와 같은 긴 문자열을 볼 수 있을 겁니다. %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16 위 부분에서 SharedSection=1024,3072,512 부분이 핵심입니다. 여기서 두 번째 항목인 3072가 데스크탑 힙으로 할당된 메모리의 크기입니다. 단위가 킬로바이트이기 때문에 계산하면 3메가가 됩니다. 저 숫자를 올려 주시면 됩니다. 8192로 지정하면 8MB가 되겠죠. 바꾸고 저장하고 재부팅하면 됩니다. |
MFC로 개발을 하면 가장 막히는 부분이 UI 개발입니다. 다른 RAD 툴에 비해서 UI 생산성이 극도로 떨어지죠. 물론 이것도 어느 정도 라이브러리가 구축되면 그닥 떨어지는 것도 아니지만, 맨땅에 헤딩해서 만들려면 장난이 아닙니다. 그래서 Xtreme Toolkit 같은 라이브러리를 사서 UI를 만드는 경우도 많이 있죠. 그런 MFC UI의 불모 지대에 희소식이 있습니다. 바로 차기 버전 MFC 부터는 Office UI를 기본적으로 지원한다는 것이죠. Office UI 기본 지원이라고 해서 'Office 97 UI를 지원하겠군' 이라는 생각을 하신다면 큰 오산입니다. 최신 Office의 리본 인터페이스를 기본적으로 제공합니다. 정말 놀랍습니다. 드디어 이런 시절이 오긴 오려나 봅니다. 개인적으로 요즘은 MFC 프로젝트를 많이 하지 않아서 조금 아쉽긴 하지만 그래도 좋은 소식이긴 합니다. 아래 페이지를 보시면 어떤 식인지 자세하게 보실 수 있습니다. http://blogs.msdn.com/vcblog/archive/2007/11/09/quick-tour-of-new-mfc-functionality.aspx 릴리즈 된다면 UI 코드를 분석해보는 재미가 있겠습니다. 늘 보면서 어떻게 만들었을지 심하게 궁금했는데... 쿄쿄쿄~~~ 설레이는데요.... |
신입 개발자를 위한 조언 분산투자와 몰빵에서 배우는 교훈 신영진, codewiz@gmail.com, http://www.jiniya.net 주가는 2000 포인트를 넘어서 고공행진을 하고 있고, 중국에 투자한 사람들은 경이적인 수익률을 몸소 체험하고 있다. 옆 집 아즘마도 주식 투자에 나섰고, 베스트 셀러 목록에서 주식 투자나 재테크 서적도 당당히 한 켠을 차지하고 있다. 바야흐로 투자 전성 시대인 것이다. 주식 투자니 재테크니 하는 책들을 보면 단골 손님으로 나오는 투자 원칙이 있으니, 바로 분산투자가 그것이다. 분산 투자란 자신의 자산을 한 군데 집중적으로 투자하지 않고 나누어서 투자하는 것을 일컫는 말이다. 그 반대를 의미하는 말로 몰빵이란 말이 있다. 자신의 전체 자산을 한 군데 몽땅 투자하는 것을 의미한다. “왜 분산 투자를 해야 하죠?”라고 묻는다면 책에서는 한 바구니에 담긴 계란은 바구니가 떨어지면 몽땅 부서지기 때문이라는 이야기를 해준다. 너무도 직관적인 비유라 사람들은 더 생각해보지도 않고 분산 투자 이론을 철썩 같이 믿고 자신의 포트폴리오를 마치 수퍼마켓 진열대처럼 만들곤 한다. 툴바(Toolbar32)를 너무 좋아한 나머지 메뉴 조차도 툴바로 만들어버린 엑셀(Microsoft Excel)팀처럼 사람들은 분산 투자의 가치를 너무나 사랑한 나머지 자신의 인생도 분산 투자를 한다. 아래 이력서는 이러한 분산 투자의 결과를 잘 보여주는 한 예다. 사용 가능한 언어: C, C++, Java, Visual Basic, C#, Delphi 이 이력서의 주인공은 C 시장이 사라져도 걱정이 없다. 자바도 조금은 할 줄 알기 때문이다. C# 문법도 어느 정도 알고 있기 때문에 자바 시장이 완전히 없어진다고 하더라도 걱정이 없다. 열거된 모든 산업이 사라지기 전까지 그는 안전하다고 생각할 것이다. 하지만 결과는 정반대다. 대부분의 채용 담당자들은 ‘할 줄 아는 것이 많다는 것은 제대로 하는 것이 없다는 것이다’라고 철썩 같이 믿고 있기 때문이다. 이력서의 주인공인 철수를 만나보도록 하자. 철수는 컴퓨터 공학과에 입학하면서 C언어를 배웠다. 너무나 재미있었다. 철수는 열심히 C언어를 익혔다. 2학년이 된 철수는 주위를 둘러보게 된다. 일 년 동안 열심히 공부했음에도 주위 친구들보다 자신이 C언어를 잘하는 것이 아니라는 생각을 한다. 이 길이 자신의 길이 아니라고 생각한 철수는 C++이라는 새로운 언어에 빠져든다. 그리곤 C++ 문법을 다시 열심히 익힌다. 열공한 철수는 C++ 프로그래머라는 이름으로 현업에 뛰어든다. 하지만 일은 하면 할 수록 어렵고, 주위에 자신보다 C++을 잘 다루는 사람은 너무도 많다. 철수는 친구들과의 술자리에서 자바 개발자들이 호사를 누리고 있다는 이야기를 듣는다. 그리고는 잘 다니는 직장을 나와서 자바 공부를 해야겠다고 결심한다. 철수 이야기가 너무 작위적이라고 생각할지도 모른다. 하지만 주변을 둘러보면 철수와 같은 선택을 하는 사람들을 너무도 쉽게 찾아볼 수 있다. 조금만 어려운 상황이 닥치면 새로운 것으로 눈을 돌리는 것이다. 그러면서 변화에 잘 적응하는 종이 오래 살아남는다는 다윈의 진화론을 자신의 선택에 대한 근거로 사용하기도 한다. 하지만 그것은 변화가 아닌 회피다. 인생은 긴 시간 동안 자신에게 투자해 나가는 과정이다. 설령 그 과정 중에 조금의 실수가 있다고 하더라도 투자 대상이 사라지진 않는다. 그래서 인생의 투자에 있어서는 몰빵이 분산 투자보다 훨씬 더 효율적이다. 물론 이 몰빵에는 중요한 두 가지 조건이 전제된다. 첫째는 자신이 진짜 좋아하는 일에 몰빵을 해야 한다는 것이고, 둘째는 적어도 몰빵한 일에 있어서는 매년 발전을 이루어야 한다는 점이다. 좋은 말로 줄여 쓴다면 선택과 집중이 되는 것이다. 영어 책만 바꿔가면서 ‘Hello, Jane’을 반복하는 사람이 외국인을 만나서 할 수 있는 이야기는 없다. 마찬가지로 프로그래밍 언어만 바꿔 가면서 ‘Hello World’를 출력하는 것은 현업의 문제를 해결하는데 전혀 도움이 되지 않는다. 하루 아침에 하늘에서 떨어진 비서 한 권으로 강호를 호령하는 내공을 얻는 이야기는 무협지 속에나 있는 것이다. 현실 세계에서의 내공은 산전, 수전, 공중전을 다 겪고도 살아 남은 자들에게 주어지는 아름다운 선물이다. |
소리통 BETA가 2007.11.8.293 버전으로 업데이트 되었습니다. 위에 있는 파일을 받으시면 됩니다. 음악 방송 청취 도중 네트워크 접속이 중단되는 경우 비정상 종료되는 문제가 해결되었습니다. 사실 이 문제는 고치는 데 몇 줄 되지도 않지만 다른 일로 제법 삽질을 했습니다. 그 이야기를 조금 해볼까 합니다. ^^;; 소리통 상단을 보면 파일 명이 큰 글씨로 출력되는 부분을 볼 수 있습니다. 외곽선 글꼴이라고 그러나요? 하여튼 뭐 테두리가 있는 글씨로 출력됩니다. 이것을 만드는 방법이 크게 두 가지 정도 있습니다. 하나는 글자를 8방향으로 돌아가면서 찍은 다음에 중앙에 실제 글자색깔로 찍는 방법이고, 다른 하나는 경로를 저장해 두었다가 StrokeAndFillPath 따위를 사용해서 그 경로를 칠하면서 동시에 테두리를 그리는 방법이죠. 딱 생각해보면 후자가 좀 더 우아해 보이지 않습니다. 그런데 실제 해보면 후자의 결과물은 꽤나 우스꽝 스럽습니다. 그래서 소리통에서는 전자의 방법으로 글자를 출력하고 있습니다. 그런데 여기서 사용하는 방법도 글자에 따라서는 조금 웃기게 출력되곤 합니다. 그래서 이걸 진짜 제대로 한 번 해결해 보고자 GDI 보다는 좀 더 기능을 많이 제공해 주는 2d 렌더링 엔진을 찾아보았습니다. 딱 떠오르는 GDI+가 있지만 처음에 그 녀석은 배제했습니다. 왜냐하면 GDI+의 경우 정적으로 링크 시킬 수가 없기 때문입니다. 무조건 DLL을 같이 배포해야죠. 물론 대부분 설치되어 있기 때문에 같이 배포하지 않아도 별 문제는 없습니다. ![]() 그림을 한 번 살펴보도록 하겠습니다. 다소 제 이름이 많이 나오는 걸 이해해 주세요. ㅋㅋ 중간 중간에 테스트 하던 것들에 대한 캡쳐 이미지가 이것 밖에는 없어서 어쩔 수 없었습니다. 처음엔 이런 내용을 쓸 줄도 몰랐거든요. ㅎㅎ 왼쪽 아래 있는 노란색 삼각형과 신영진이란 테두리가 있는 글씨가 GDI+대신 사용한 agg란 2d 렌더링 엔진으로 출력한 샘플 입니다. 여기까진 굉장히 만족스러웠습니다. 보시면 알겠지만 삼각형의 라인이 겹치는 부분이나 대각선에 안티알리아싱이 적용된 것을 보시면 깔끔하게 처리된 것을 알 수 있습니다. 외곽선 글꼴도 그냥 저냥 쓸 수 있겠다고 생각하고는 이 녀석을 소리통에 적용하기 시작했습니다. 그런데 이 판단엔 큰 실수 였습니다. 하나는 큰 글씨로 테스트 했다는 것이고, 다른 하나는 그 글꼴도 맑은 고딕으로 테스트를 했다는 점 입니다. 다들 아시겠지만 맑은 고딕은 클리어타입과 같은 안티알리아싱 기술에 최적화된 글꼴 입니다. 클리어타입을 적용하지 않고 보면 완전 엉망이죠. 하지만 적용하면 글꼴의 차원이 달라집니다. 이제 문제를 살펴보겠습니다. 그림에서 오른쪽을 살펴보면 메모장이 있습니다. 보시면 이름이 선명하게 출력된 것을 볼 수 있습니다. 이제는 오른쪽의 소리통에 출력된 글씨를 살펴 봅시다. 흐릿하게 보일 겁니다. 확대한 그림이 각각 옆에 있습니다. 안티알리아싱 때문에 글이 뭉개진것처럼 보이는 것을 알 수 있습니다. 아마 Photoshop을 해보신 분들은 대부분 이런 것들을 겪어 보셨을 겁니다. agg 라이브러리의 경우에 기본적으로 GetGlyphOutline이라는 함수를 사용해서 글꼴의 외곽선을 추출하고 그것을 다시 자신의 오브젝트에 넣어서 렌더링을 시킵니다. 결국 크든 작든 모두 다 벡터 방식으로 그려지는 것이죠. 그렇다면 안티알리어싱만 적용하지 않으면 될까요? 알아보지도 못할 글자가 출력된답니다. 윈도우는 작은 글꼴일 경우에는 글꼴에 저장되어 있는 비트맵을 사용하기 때문에 깔끔한 글꼴이 출력된답니다. 결국 agg를 쓰게 된다면 작은 글꼴은 다시 DC 함수로 적어줘야 하는 상황이 됩니다. 그렇게 하는 것이 불가능하지는 않지만 괜히 두 번 작업하는 것이 맘에 들지 않아서 GDI+를 사용해야 겠다고 생각을 했습니다. GDI+는 과연 배포 문제만 제외한다면 모든 조건을 만족시킬까요? 하지만 안타깝게도 아니었습니다. GDI+의 경우는 안티알리아싱 알고리즘에 문제가 있어 보였습니다. 오른쪽 아래 있는 화면이 GDI+를 사용해서 경로를 추출해서 외곽선 글꼴을 그린 샘플입니다. 다른 글꼴에서는 문제가 덜 했는데 바탕체로 출력하니 정말 흉하게 되더군요. 녹색 상자가 있는 A 부분을 보면 정말 심하다는 것을 알 수 있습니다. 검은 부분이 위로 튀어나와 있죠. High 퀄리티 이상의 출력 옵션을 적용하는 경우에는 모두 저렇게 되었습니다. 안티알리아싱을 끄면 거의 보지 못할 만큼 흉한 글이 출력됩니다. (최신 GID+는 어떨지 모르겠습니다. Windows XP에 기본적으로 설치된 것으로 테스트한 것입니다.) 결국은 다시 원점으로 돌아와서 GDI에 그냥 8방향에 출력하는 것으로 해두었습니다. 돌아서서 생각해보니 GDI와 agg를 같이 쓰는 것도 별로 나쁠것 같진 않네요. agg의 경우 DC와 같이 작업하기 편리하게 되어 있기 때문에 굳이 하나만 고집할 필요도 없어 보입니다. 생각보다 쓸만한 2d 렌더링 엔진이 별로 없다는데 놀랐습니다. 제가 사용했던 agg 라이브러리는 여러 가지 면에서 굉장히 뛰어났습니다. 사실 거기 있는 샘플들을 구동해 본다면 라이브러리가 얼마나 많은 기능을 지원하는지 알 수 있습니다. 하지만 문서가 거의 없어서 소스를 보고 분석해서 사용해야 한다는 점이 좀 단점이었습니다. 괜찮은 엔진이나 외곽선 글꼴을 만드는 방법을 알고 계시다면 코멘트 달아주세용 ^^;; |
이번 달 원고에 캡쳐한 이미지가 제법 많은데 인쇄해서 나오니 리사이즈 되기도 하고, 반전 부분이 노란색이라 잘 표시가 되지 않더군요. 안그래도 글이 서툴러서 이해하기가 힘드실텐데, 인쇄된 이미지까지 이상해서 보시는 분들 고생이 이만저만이 아닐듯 싶습니다. 앞으로는 반전 부분에 주의를 기울이도록 하겠습니다. 글에 포함된 이미지 중에서 인식하기가 힘든 것들만 첨부했습니다. 글과 같이 대조해 가시면서 보시면 이해하는데 도움이 될 것 같습니다. 빠른 시일 내에 원고 원문을 올려놓도록 하겠습니다. P.S) 일 년에 한 권 마소를 산다면 11월호를 사야할 것 같습니다. 이번 달 완전 대박이더군요. 마소 안보시는 분이라도 개발자라면 꼭 한 권 사서 보기를 권해드립니다. 개발 고수 7인의 천기 누설 "수퍼 개발자로 가는 길" 이거 장난이 아닙니다. ㅎㅎ^^;; 이런데 아니라면 쉬이 읽기 힘든 글이죠. 내용도 알차고 참 좋네요. 다 읽진 못하고 앞에 유명하신 몇몇 분들 글만 읽었는데 도움이 많이 되는 것 같습니다. 안영회님의 "개발자를 위한 여섯 가지 실천 지침"도 상당히 공감하면서 읽었습니다. 마소가 창간 24주년이라고 합니다. 앞으로도 쭈욱 발전했으면 좋겠네요. 더불어 국내에도 개발자를 위한 다양한 잡지가 나오기를 기대해 봅니다. 그나마 프세가 같이 있던 시절이 좋았는데 말이죠. ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() 지난 번 릴리즈에 있었던 몇 가지 버그를 수정한 버전입니다. 2007.11.2.293 버전을 사용하신다면 업데이트 버전을 사용하시는 것이 컴퓨터 건강에 좋습니다. 버전: 2007.11.5.87 1. 필터와 관련된 메모리 릭 문제가 해결되었습니다. 2. 소켓이 제대로 닫히지 않던 버그가 수정되었습니다. 3. 프로그램 시작 시 안정성이 향상되었습니다. 4. URL 추가 창의 탭 순서가 수정되었습니다. 5. 음악 방송 중지 시 안정성이 향상되었습니다. 6. 재생 취소 시 다음 곡으로 자동으로 넘어가는 문제가 해결되었습니다. |
![]() 소리통 BETA가 업데이트 되었습니다. 근 십만년 만인것 같네요. 바쁘기도 하고 그닥 관심도 가지 않아서 업데이트 하지 못했습니다. 보기에 달라진게 없다구요. ㅎㅎ 맞습니다. 외관상 변경된 것은 없습니다. 다음과 같은 기능이 추가되고 문제가 해결되었습니다. 버전: 2007.11.2.293 1. 음악방송(ShoutCAST) 청취 기능 추가 2. 종료시 안정성 향상 3. 크기 조절시 안정성 향상 사실 머 2,3번은 그닥 크게 눈에 띄지 않는 업데이트죠. 아마 기존에 문제를 겪지 않으셨다면 잘 모를것 같은 부분입니다. 역시나 이번 업데이트의 백미는 음악방송 청취 기능 추가 입니다. ㅎㅎ 메뉴에서 음악방송 추가를 선택하면 아래와 같은 화면이 나타납니다. 여기다 음악방송 주소를 넣고 확인을 누르면 방송을 청취할 수 있습니다. ![]() 보잘것 없는 기능만 가지고 있지만 많이들 사용해주세요. ^^;; 버그 신고나 기능 추가및 건의 사항은 이 글 댓글이나 메일 주시면 되겠습니다. 사용해 보고 싶으신 분들은 아래 압축 파일을 받으시면 됩니다. |
중학교 때 였습니다. 우리반 양아치 한 명이 조양은씬가? 김태촌씬가? 하는 사람이 쓴 책을 들고 와서는 깡이 젤 중요하다는 이야기를 하루 종일 했습니다. 서방파가 어떻고, 양은이파가 어떻고 하는 이야기에서 싸움 보다 깡이 중요하다는 머 그런 이야기였죠. 그런 쓰잘때기 없는 이야기를 체육 시간 내내 들어주며, 깡같은 소리 하고 있네라고 속으로 생각했었죠. 오늘 갑자기, 불현득, 쌩뚱맞게 그 때 생각이 나더군요. 십년도 더 된 그 체육 시간이 말입니다. 그리곤 그 녀석 말이 맞는지도 모른다는 생각이 들기도 했습니다. ㅋ 곰TV를 보고 있었습니다. 박태민 선수와 김택용 선수가 MSL 4강전을 한다더군요. 심심하던차에 재밌겠다 싶어서 틀었습니다. 오. 김택용 선수, 게임도 잘하는데 얼굴도 잘생겼습니다. ㅋㅋ 꽃미남인데 라는 생각을 잠시하며 결과가 어떻게 될지를 지켜보고 있었습니다. 1경기 어이없게 한방 러시에 박태민 선수가 GG, 2경기 어이없게 몰래 멀티 늦게 발견해 물량에 김택용 선수가 GG. 3경기 였습니다. 박태민 선수 나름대로 분위기 좋았습니다. 히드라 걸어가도 좋고, 드랍 성공하면 더 좋은 상황. 그런데 오버로드가 재수 없게 다 잡혀 버렸습니다. 오버로드 다 잡힌 순간 바로 GG치고 나가더군요. 보는 입장에서 조금 난감했습니다. 물론 자신의 판단에 안될수도 있겠다고 판단할 수 있지만 너무 어이없게 빠른 지지더군요. 그 다음 경기는 김택용 선수의 포토러시에 당해서 졌습니다. 결국 김택용 선수가 결승 진출을 했습니다. 몇 일전 이었습니다. 새벽에 잠도 오지 않고 곰TV에서 이성은 선수와 마재윤 선수의 8강전을 보고 있었습니다. 당연히 마본좌님께서 싱겁게 이겼겠군 하면서 첫번째 경기를 틀었습니다. 50분 가량 진행된 경기, 이성은 선수 본지 초토화 됐습니다. 포기하지 않고 8시 멀티에 재건하고 배틀 모으더군요. 이 무슨 시츄에이션하는 생각을 잠시 했습니다. 그러더니 꾸역꾸역 섬멀티 하나 밀고 먹습니다. 배틀 모으고, 베쓸 모으고, 메딕 리스토레이션 개발하고, 나머지는 쇼타임이더군요. ㅋㅋㅋ 심하게 재밌는 경기였습니다. 예상을 뒤집은 역전이어서 더욱 그랬습니다. 중간 중간에 나오는 이성은 선수의 센스있는 플레이 또한 경기를 재밌게 만드는 원동력이었습니다. 결국 3:2로 이성은 선수가 4강에 진출했습니다. 승부의 세계에서 깡은 정말 중요합니다. --- 곰TV MSL 시즌2 할 때 작성된 글 입니다. 아직 위에서 언급된 경기를 보지 못했다면 아래 주소에서 보실 수 있습니다. 마재윤 vs 이성은 경기는 정말 재밌습니다. 전체 순위에서도 당당히 1등이군요. ㅋㅋ 시즌3에서 이성은 선수는 아쉽게 초반 탈락했고, 김택용 선수는 4강에 진출한 상태입니다. MSL은 이상하게 연속 우승하는 선수가 많은것 같아요. ㅋ 김택용 vs 박태민 마재윤 vs 이성은 |