정말 엄청난 실력을 가진 해커이다. 특정 플랫폼이나 언어에 상관없이 여러 주제로 재밌는 글을 쓴다. 가끔 기괴한 코드 골프 내용이 올라오기도 하는데 그런걸 쳐다보고 있다 보면 자괴감에 빠지기도 한다.
어쨌거나 나는 그의 글이 너무나도 좋아서 언젠가는 주말 이틀 동안 내내 방구석에 누워서 2004년부터인가 썼던 모든 글을 다 읽어본 적도 있었다. 가끔씩 이상한 오락실 얘기도 쓰고는 하는데 그런 글조차 재밌다. 블로그에 댓글로 피드백을 할 수가 없어서 애독자로서 좀 아쉽긴 하지만 본인이 그에 대해 많이 고민해 본 듯하니 어쩔 수 없는 일이다.
프로그래머가 몰랐던 멀티코어 CPU 이야기를 쓴 저자이다. 주로 윈도 프로그래밍이나 시스템 프로그래밍 이야기를 다루는데 글들이 재밌을 뿐더러 배울 점도 많다. 이 블로그 역시 거의 모든 글을 다 읽었다. 아마 프로그래밍 기술을 다루는 우리나라 블로그들 중 가장 피드백이 많이 왔다갔다 하고 방문자 수도 많은 블로그가 아닐까 싶다.
이 블로그는 비교적 최근에 알게되었다. 글들은 아주 오래전부터 꾸준히 작성되어 왔는데 써있는 글의 질과 양에 비해 일방문자수는 상당히 적다. 윈도 프로그래밍에 대해서만 다룬다. 윈도 역사에 대해서 글을 쓸 때는 레이몬드 첸을 보는 느낌이 들기도 한다. 철도와 종교 이야기도 종종 꺼내는데 나는 그런 주제는 관심이 없어서 건너 뛰고 읽는다.
그러고보니 이 블로그들 이상으로 예전에 정말 좋아했던 블로그가 있었다. 바로 방준영의 블로그. 2009년도 즈음이었던가? 어느 날 아침에 그의 블로그를 발견하고는 오아시스라도 발견한 것 처럼 기뻤던 날이 있었다. 거의 매일 같이 좋은 글들이 올라와서 정말 행복하게 읽어가고 있었는데 언제부터인가 새 글이 더 이상 올라오지 않았고 심지어는 기존에 썼던 글마저 사라져 버렸다. 안타까운 일이다. 준영님. 혹시라도 이 글을 보신다면 돌아와주세요. 엉엉.
나는 미투데이나 트위터가 싫다. 페이스북도 싫다. 이 잡 것들이 나오고 나서 사람들은 블로그에 글을 잘 쓰지 않는다.
돌아오라 블로거들이여. 맛집 블로거 말고 프로그래머들 말이여.
그럼에도 불구하고 영어 블로그는 여전히 좋은 블로그들이 엄청나게 많다. 하지만 영어 블로그를 읽는 것은 정말 고통스러운 일이다. 내 피드 리더에는 나중에 읽으려고 마킹해둔 글들이 잔뜩 쌓여있는데 그것들 대부분은 영어 포스트이다. 한 번 읽으려면 크게 심호흡부터 하며 각오를 단단히 하고는 한다. 그리고 나는 그렇게 심호흡을 자주 하지 않기 때문에 오늘도 마킹만 해두는 글들이 계속 늘어간다.
그러니 이렇게 우리말로 좋은 글을 써주는 사람들이 어찌 고맙지 않겠는가. 좋은 국내 블로그들이 더 많이 생겼으면 좋겠다.
안녕하세요? 제 블로그에 흔적을 남겨 주신 것에 감사드리며, 저와 제 지인의 블로그를 소개해 주셔서 또 감사합니다. ^^
'1. 메아리 저널의 운영자'는 저의 학교 후배이고 저와도 아주 친한 사이입니다.
'엄청난 실력을 가진 해커' ← 사람 보는 안목이 정확하십니다. ㄷㄷ
짐작하신 대로 저는 아주 좁은 제 전문 분야만 빼면 딱히 다른 IT 기술이나 플랫폼이나 전산학의 발전에는 큰 관심이 없는 타입이에요.
그에 반해 진정한 전산학 덕후/해커가 어떤 사람인지를 저 친구를 보면서 저는 절실히 느낀답니다. ^^
김민장 님 블로그는 운영자께서 대학원 생활에 너무 바쁘셔서 유명세에 비해 글이 너무 뜸하게 올라온다는 것만이 유일한 단점인 듯하고...
제 블로그는 설치형이어서 메타블로그에 딱히 노출되는 게 없습니다. 그래서 예전부터 제가 개발한 프로그램을 사용해 온 분이나 너무 매니악한 블로그 주제에 질리지 않은 분들만 오느라 방문자수가 적은 것 같습니다. ^^;; 2년 전이나 지금이나 비슷한 수입니다.
블로그 주제가 꽤 이상한 혼합형 타입이죠? ㅋㅋㅋㅋ
URL에서 tc를 빼고 도메인만 입력해서 접속하면 대문 페이지도 나오는데, 그것도 보셨나 궁금합니다.
그렇다면 다음 코드는 어떨까? 이번엔 CString이 아니라 std::wstring을 사용했다.
std::wstring s = L"abc";
wprintf(L"%s", s); // this is wrong
컴파일은 잘 되지만 이번엔 제대로 출력되지 않는다. 형식 문자열에 포인터를 넣지 않고 wstring 객체 자체를 쑤셔 넣었기 때문이다. 사람들이 흔하게 하는 실수이며, 경험있는 프로그래머들이 형식 문자열을 사용하지 말라고 하는 이유이다.
제대로 출력하려면
wprintf(L"%s", s.c_str());
이렇게 써주어야 한다.
아니 그런데 왜 CString은 그냥 넣어도 잘 되고 std::wstring은 .c_str() 함수를 호출해야만 되는걸까. CString에 뭔가 비밀이 있는건가.
있다.
조금 더 주의 깊은 사람들은 CString의 구현을 살펴보고 LPCWSTR에 대한 형변환 연산자가 정의되어 있는 것을 발견해낸다. 아, 형변환 연산자가 있기 때문에 자동으로 형 변환이 되는거구나.
하지만 이는 형변환 연산자 때문이 아니다.
가변 인자 함수로 들어갈 때는 형변환이 발생하지 않는다. 함수 파라메터가 '가변'이고 무슨 타입이 들어올지도 적혀 있지 않는데 어떤 타입으로 형변환을 하는가?
CString의 코드가 잘 동작할 수 있는 비밀은 CString의 멤버 변수가 실제 문자열 데이터를 가리키고 있는 포인터 m_pszData 하나 밖에 없기 때문이다. 가상 함수도 없다. 객체의 맨 앞에 포인터를 가지고 있다는 것이 중요하다.
그림으로 그려보면 이렇게 생겼다.
재밌지 않은가? 문자열 클래스가 문자열 길이를 위한 변수도 가지고 있지 않고 달랑 WCHAR* 하나만 가지고 있다니.
하지만 CString의 은밀한 곳에서는 메모리를 조금 더 할당해서 문자열 길이나 레퍼런스 카운트를 저장하고 CString에게는 pszData 하나만 노출시켜 놓는다. 그리고 이렇게 설계한 이유는 사람들이 저런 실수를 하더라도 잘 동작하도록 만들고 싶었기 때문일 것이다.
하지만 잘 동작한다고 해서 그렇게 쓰는 것이 옳다는 것은 아니다. 가변인자의 파라메터로는 POD 만 들어갈 수 있다. NON-POD 타입이 들어갈 경우에는 모두 undefined behaviour이다. 나중에는 컴파일러의 구현 변경에 따라 동작하지 않게 될 수도 있다는 뜻이다. -말은 이렇게 하지만 그런 일은 좀처럼 발생하지 않는다.
파일 오퍼레이션을 잡아챌 수 있다고 해서 이 훅을 사용해 파일 삭제 등을 감시하는 모니터 용도로 사용하려는 아이디어는 좋지 못하다. 이 기능은 모든 파일 시스템 오퍼레이션에 훅을 제공하는 것이 아니라 폴더 삭제와 같은 특정한 몇몇 동작에 대해서만 동작하기 때문이다. 어떤 파일 오퍼레이션이 발생하는가 궁금한 거라면 파일 시스템에서 제공하는 파일 변경 알림 기능을 사용하는 것이 올바른 방법이다.
그럼 이 인터페이스는 도대체 어디에 쓰라고 만든 물건이고.
윈도우 탐색기에서 폴더를 삭제하게 되면 탐색기는 폴더 안에 있는 파일들부터 모두 지우고 마지막에 폴더를 삭제한다. 이는 NTFS 같은 파일 시스템이 폴더에 파일이 있으면 삭제하지 못하도록 하고 있기 때문이다. RemoveDirectory 함수를 호출했을 때 해당 디렉터리 내에 파일이 존재한다면 파일 시스템 드라이버는 STATUS_DIRECTORY_IS_NOT_EMPTY 에러를 돌려주도록 구현해야 한다. 윈도 탐색기의 이런 동작은 네트워크 파일 시스템 위에서는 치명적이다. 로컬 파일 시스템이라면 Irp가 몇 백번쯤 왔다갔다해도 금새 끝나겠지만 레이턴시가 긴 네트워크 파일 시스템 같은 경우는 저 멀리 미국까지 백 번 천 번을 왔다 갔다 해야 할 수도 있는 것이다.
ICopyHook 을 사용하면 이런 폴더 삭제나 이동 명령들을 먼저 잡아채서 내 마음대로 원하는 동작을 수행 한 뒤 ID_NO를 리턴함으로서 쉘에게는 더 이상 오퍼레이션을 하지 않도록 할 수 있다. 예를 들어 네트워크 파일 시스템 드라이버를 만든다면 쉘에서 폴더 삭제 같은 오퍼레이션이 발생할 때 이를 잡아채서 서버로 폴더 삭제 명령을 딱 한번만 보낼 수 있는 것이다. 물론 서버는 하위에 파일들이 있더라도 폴더를 삭제할 수 있는 기능을 지원해야 한다. 다른 많은 경우들에도 이 기능을 응용할 수 있을 것이다. 상상의 나래를 잘 펼친다면.
주의 해야 할 점은 내 훅이 실행될 때 어떤 에러가 발생하면 에러메세지를 사용자에게 보여주는 것도 내 책임이 된다는 것이다. ID_NO를 리턴하면 쉘은 해당 오퍼레이션에 대해서 더 이상 신경쓰지 않는 것을 기억하라. 함수의 첫 번째 인자로 들어오는 HWND는 바로 그런 사용자 인터랙션을 위해서 존재한다.