« Previous : 1 : ... 221 : 222 : 223 : 224 : 225 : 226 : 227 : 228 : 229 : ... 230 : Next »

인천 공항 스타라인

인천 공항 내부에 있는 스타라인이라는 무인 경전철은, 인천 공항에 확장 탑승동이 지어진 관계로 main 여객 터미널과 확장 탑승동을 연결하기 위해서 활주로 지하에 건설되었다. 둘 사이의 거리는 거의 900미터 정도 된다고 한다.
완공도 작년 6월이니 얼마 되지 않았으며, 한창 내가 병특 마칠 무렵에 생긴 것이었다. 작년에 미국 갔다 올 때도 이미 있었다는 얘기인데 나는 물론 그땐 그런 게 있다는 걸 알지 못했다.

물론 타는 곳은 승차권을 소지하고 보안 검색과 출국 신고까지 마친 승객 당사자만 들어갈 수 있는 ‘면세 구역’에 있기 때문에 일반 공항 방문객이 이걸 이용할 수는 없다. 확장 탑승동은 전구간이 면세 구역이다. 지난 3월 말에 중국 갔다 올 땐, 겨우 1시간 남짓 제주도 거리밖에 안 되는 노선을 이용하는데 탑승구까지 가느라 시껍을 했다. 비행기에서 내린 직후 공항의 면세 구역을 완전히 벗어나 환영객이 기다리고 있는 출구까지 나가는 데 거의 30분은 걸린 것 같았다. 수하물 찾을 것도 없었는데도! 아예 비행기 탑승권 뒷면에도 “탑승구가 졸라 멀리 떨어져 있으니 공항에 꼭 충분히 일찍 오셔야 합니다” 주의 사항이 찍혀 있었다.

스타라인 자체에 대해서 얘기를 좀 더 하자면, 일단 서울 지하철이나 심지어 공항 철도와도 굉장히 다르다. 차량은 3량 1편성이며, 운전석이 없는 무인 열차여서 앞뒤 터널 경치를 볼 수 있다. (물론 차량 자체도 일본에서 도입한 거라고 한다) 그리고 고무 바퀴이다. 한 편성 안의 모든 차량이 같은 외형으로 생겼으며 객실과 객실 사이를 이동할 수 없다. 다수의 항공 여객을 아주 짤막한 시간 동안만 수송하는 차량의 특성상, 좌석은 소수의 노약자석 말고는 없다.

또 하나 매우 중요한 사실이 있다.
재미 삼아 한 열차 안에서 짱박고 있다가 왔던 길로 되돌아가면 되는 일반 광역전철과는 달리, 이 열차는 장난으로 탈 수가 없다. 이 열차를 타기 위해 별도의 승차권이라도 사야 하는 것도 아니고 완전 무료인데도 왜 그럴까? 교통수단별로 시스템의 차이를 살펴보자.

고속버스 터미널은 심지어 승차권 없이도 아무라도 승강장까지 갔다가 잠시 차내에 들어가서 배웅을 하고 올 수도 있다. 한 차의 승객이 적기 때문에, 승차권 검사는 어차피 출발 직전에 차내에서 이루어진다.
그 반면 철도는 역내에 개집표기가 있어서 마치 고속도로의 톨게이트처럼 paid 영역과 non-paid 영역이 엄격하게 구분되어 있다. 일반 열차역의 경우 비승객이 paid 영역에 잠시 들어갔다 나오려면 입장권을 구매해야 한다. 비승객이 열차 객실 내부까지 들어가는 것을 금지는 하고 있으나 이를 막을 방법은 없다.

이제 국제선 공항은 어떨까? 입장권 같은 건 꿈에도 상상할 수 없다. (면세점 쇼핑 좀 하려고 입장권 구입? ㅋㅋㅋ) paid 영역 안에서도 출발 승객과 도착 승객이 드나들 수 있는 구간은 매우 엄격하게 분리되어 있다. 출발(출국) 승객과 도착(입국) 승객을 엄격하게 분리시켜야 하기 때문에, 스타라인 같은 열차 안에서도 두 부류의 승객이 섞여서는 절대 안 된다.
이런 이유로 인해 한번 여객 터미널에서 확장 탑승동으로 이동한 출국 승객은 다시 터미널로 돌아올 수 없으며 매번 열차는 한쪽 출입문을 열어서 모든 ‘출국’ 승객이 내린 것을 확인한 후에 거길 닫고 반대쪽 출입문을 열어서 ‘입국’ 승객을 받아들인다.

공항에 따라서는 여객 터미널과 탑승동이 일체로 연결되어 있지 못해서 paid 영역으로 들어간 후, 공항 건물에서 비행기까지나 또는 그 반대로는 저상 버스를 또 타고 이동하는 경우도 있다. 하지만 인천 공항은 그런 게 없고 모든 탑승구가 건물로 연결되어 있다. 철도역으로 치면 역사와 승강장이 따로 있는 옛날 역과, 100% 선상역으로 지어지고 있는 요즘 역의 차이 정도 된다고 할 수 있다.

그나저나 항공업계는 어찌 보면 가장 세계화 텃세가 강한 분야임에도 불구하고 대한 항공이 ‘코에어’로 사명을 바꾼다던가, 요즘 전철까지 유행처럼 번지고 있는 ‘승객’ -> ‘고객’ 이런 트렌드는 없는 것 같다.

Posted by 사무엘

2010/01/11 09:34 2010/01/11 09:34
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/62

우주 탐사선들

인류가 만들어 낸 인공물(artifact) 중 현재 지구에서 가장 멀리 떨어져 있는 것은 우주 탐사선 보이저 1호/2호이다. 태양계를 떠나 지구로부터 한없이 멀어지고 있는 탐사선은 파이어니어 10/11호밖에 없는 줄 알았는데, 이것 말고도 더 있다는 걸 알게 됐다.

http://blog.naver.com/bk210850/140001208301
이들은 이미 태양-해왕성 사이 거리의 두 배에 달하는 지점마저 넘어섰다.

파이어니어 10호의 경우 2003년 초에 정말 가냘픈 신호가 감지된 것을 끝으로 교신이 영영 끊겼고, 이제는 수명이 다 해 죽은 것으로 추정된다. 하지만 보이저 탐사선은 지구로부터 100수십 억 km나 떨어져 태양계의 거의 끝자락에 도달했음에도 불구하고 지금도 예상 수명을 훨씬 초과하여 살아 있고 활동 중이라 하니, 정말 놀랍지 않을 수 없다. 물론, 그렇게도 멀리서 오는 탐사선의 미약한 전파를 잡아내려면 정말 넓고 크고 성능 좋은 안테나들을 세계 각지에 설치해 놔야 한다.

  (파이어니어 10호는 2000년 말에도 교신이 한동안 끊겨서 이거 실종이 아닌가 싶었으나 2001년 5월에 다시 신호가 와서 관계자들이 안도한 적이 있었다.)

무려 30여 년 전, 박통 시절에, 인텔에서 이제 막 4비트/8비트 마이크로프로세서를 만들어 내던 시절에 발사된 우주 탐사선이 지구로 각종 행성들의 사진을 보내 왔다는 게 정말 믿기 힘들다. 하다못해 JPG 압축 알고리즘도 없던 시절인데 말이다.
본인의 경우, 처음 봤을 때의 전율과 감격을 아직도 잊을 수 없는 사진이 뭐냐 하면 달 뒷면의 모습, 그리고 달과 지구가 나란히 포즈를 취하고 한 사진에 찍혀 있는 모습이다. 달은 지구에 비해서 얼마나 비정상적으로 기괴하게 큰 위성인지를 한눈에 알 수 있다. 인류가 이런 정보와 지식을 얻기까지 몇 년이 걸렸던가!

1960, 70년대엔 냉전 구도 때문이었는지는 모르겠으나 미국과 러시아가 우주 개발이 한창 전성기였다. 어떤 놈은 금성과 수성의 표면을 관측한 뒤 임무를 마치고 태양을 돌다가 과열되어 최후를 마치기도 했고, 어떤 놈은 금성 대기권에서, 어떤 놈은 금성 표면에서 1시간을 버티다 고열 고압을 견디지 못하고 파괴되기도 했다. 탐사선 이름은 기억 안 나는데, 목성 착륙을 시도하다가 그대로 파괴되어 버리고 연락이 끊긴 놈도 있었다. 목성은 크기만 작을 뿐 내부 성분은 태양 같은 항성과 완전히 똑같다고 하니, 착륙했다간 그 길로 짙은 고압 유독가스에 모든 게 분해되어 버릴지도 모르겠다. Quake 3 Area에 나오는 Fog of Death가 생각난다.

그런 시도가 있은 후 어떤 놈은 그렇게 특정 행성에서 말뚝 박고 최후를 마치는 게 아니라 아예 태양계 밖으로 영원한 질주를 시작한 것이다. 기존 행성의 중력을 이용하여 나름 초속 수십 km로 주행한다 하지만 그래 봤자 한 행성에서 다른 행성까지 가는 데 꼬박 2~3년씩 걸린다. 지구와 전파를 교신하는 데도 수십 분에서 한두 시간은 족히 걸린다. (태양-지구 사이의 거리인 1 천문단위가 전파로는 8분 20초 가량 소요)

그런데 여기서 중요한 것은, 자체 연료도 없는 우주 탐사선이 아무 때에나 그렇게 기존 행성의 중력을 잘 이용하여 태양계 바깥으로 갈 수 있는 게 아니라는 사실이다. 정확한 사항은 기억이 안 나지만, 1970년대 중반이 외행성들이 거의 일렬로 배열되어 백수십 년마다 한 번 찾아올까 말까 하는 절호의 기회였다고 한다. 이것도 어쩌면 영적으로 볼 때 우연은 아닌 것 같다. -_-;;

탐사선의 궤도를 계산하고 탐사선이 그 암흑천지 우주 공간 속에서 일말의 에너지를 받아서 전력을 생산하고 더구나 사진까지 찍고 지구와 교신하는 건 정말 수학과 과학 첨단 기술의 승리라고밖에는 말할 수 없다. 광량이 절대적으로 부족한 곳에서 항성도 아니고 행성 사진을 어떻게 저렇게 찍었을까? (극악의 노출 시간 동안 있는 빛 없는 빛 다 긁어모아서 찍지 않았겠나? -_-) 육안으로는 지구에서 관측할 수 없는 천왕성만 해도 아직까지 우주 탐사선이 보내 준 사진의 질이 별로 좋지 못하며, 그저 희뿌연 구 형상만 파악할 수 있는 실정이다.

컴퓨터의 발전 속도도 놀랍지만
어떻게 인간이 자체 동력으로 하늘을 나는 데 성공하고서 겨우 반세기 남짓만에 민간인 여객기가 전세계를 연결하기 시작하고 인공 위성을 띄웠으며 이내 우주 왕복선과 탐사선이 발사되었을까? 그런데 한편으로는 그로부터 거의 40년이 또 지난 지금은 왜 우주 개발 쪽으로 아무런 진척이 없을까? 신기하기 그지없다.

또한 우주를 아무리 뒤져 봐도 아직까지 태양과 지구 같은 이런 행성-항성 조합은 발견되지 않았고 생명 또한 발견되지 않은 것도 경이롭다. 달은 자전 주기와 공전 주기가 정확하게 일치하여 지구에서는 뒷면이 절대로 보이지 않으며, 지구에서 달의 겉보기 크기가 태양의 겉보기 크기와 일치하는 것도 우연이라고는 도저히 받아들일 수 없는 이상한 점인 것은 틀림없어 보인다.

Posted by 사무엘

2010/01/11 00:45 2010/01/11 00:45
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/60

우리는 C/C++ 언어에서 포인터란, 정수와 비슷한 형태이긴 하나 일반적인 숫자가 아니라 메모리 주소를 가리키는 특수한 자료형이라고 배운다. 포인터는 하드웨어 친화적이고(기계 입장에서 아주 직관적임) 매우 강력한 프로그래밍 요소이지만, 그만큼 길들여지지 않은 야생마처럼 위험 부담이 크다. 포인터 자체하고 포인터가 가리키는 메모리 영역이 따로 놀 가능성이 언제든지 있기 때문에 memory leak, dangling pointer 같은 위험에 노출되기가 매우 쉽다. 자유라는 약이 무질서라는 독으로 변질될 여지가 큰 것이다.

포인터의 값은 다른 지역/전역 변수의 주소로부터 얻어지거나 아니면 메모리 할당 함수를 통해 생성된다. 우리가 직접 상수 값을 대입하는 경우는 거의 없으며, 두 포인터의 값의 차이를 상대적으로 비교하는 경우는 있을지언정, 포인터가 나타내는 그 숫자 자체는 프로그래머에게 사실상 아무 의미가 없다.

사실 이 숫자가 무엇을 의미하는지는 C/C++ 언어의 영역이 아니라 그 언어를 돌리는 플랫폼 내지 운영체제의 영역으로 넘어가게 된다. 포인터란 그만큼 저수준인 존재이며, C++ 이후에 등장한 더 진보한 언어들은 포인터를 더 다루기 편하고 덜 위험한 형태로 어떻게든 감싸고 포장하고 더 상위 계층을 만들려고 애쓰고 있다.

우선 0은 NULL 값으로 유명하며, 윈도우 운영체제의 경우 0뿐만이 아니라 그 이후 0xFFFF 번지까지가 모두 오류로 간주된다. 즉, 이 영역은 운영체제가 어떤 경우에도 메모리를 가리키는 주소로 절대 인정하지 않으며, 오히려 응용 프로그램이 일반 숫자를 포인터로 착각하고 잘못 사용한 것으로 간주하여 무조건 오류를 일으켜 주겠다는 뜻이다. 이런 정책은 사실 프로그래머에게 굉장히 유용하다. 16비트 범위 안에 드는 작은 숫자는 메모리 주소보다는 인덱스 번호 같은 일반 숫자의 의미를 갖는 경우가 훨씬 더 많기 때문이다.

그 후 32비트 윈도우를 기준으로, 64KB부터 2GB까지는 응용 프로그램이 마음대로 사용할 수 있는 “사용자 영역”이다. 이 공간에 나의 EXE, DLL들이 로딩도 되고, 스택/힙 같은 메모리 공간이 할당되고 모든 일이 일어난다. 한 프로세스는 다른 프로세스의 이 영역을 넘볼 수 없다.

단 여기서 잠깐 예외가 있는데, 윈도우 9x는 앞부분의 64KB부터 4MB까지가 또 도스 및 16비트 윈도우 프로그램과의 호환성 유지를 위한 고정된 공용 주소로 예약이 되어 있다. 이런 이유로 인해 윈도우 9x는 4MB에 해당하는 0x400000보다 낮은 메모리 주소에다가는 32비트 바이너리를 불러올 수 없다. EXE/DLL의 preferred base가 이보다 더 낮은 주소인 데다가 재배치 정보까지 들어있지 않다면 그 바이너리는 윈도우 2000/XP 이상에서는 실행 가능하지만, 9x에서는 실행할 수 없게 된다. 비주얼 C++을 보면 EXE의 디폴트 기준 주소가 0x400000으로 잡혀 있는데, 이것은 윈도우 9x와의 호환성을 고려한 귀결이다.

NT급 윈도우는 0x80000000부터 커널이 사용하는 메모리 영역이 시작된다. 쉽게 말해 32비트 포인터로 가리킬 수 있는 4GB의 영역을 응용 프로그램이 2GB, 커널이 2GB로 반반씩 나눠 쓴다는 뜻이다. 물론 여기 부근에도 NT 계열과 9x 계열 윈도우는 메모리를 사용하는 방법이 대동소이한 차이가 존재한다.

NT급 윈도우에는 0x80000000 이전의 64KB 공간을 또 떼어서, 프로그래밍의 편의상 무조건 사용하지 않고 여기에 접근하는 것을 에러로 간주하는 영역을 또 두고 있다. 0~0xFFFF의 용도와 마찬가지이며, 말 그대로 사용자 영역과 커널 영역 사이에 안전을 위해 마련해 놓은 "메모리의 비무장 지대"인 셈이다.

한편 9x 계열은 그런 것은 존재하지 않는다. 대신 0x80000000부터 0xC0000000 사이의 1GB를 “공유 메모리 전용 영역”으로 지정하여, 일부 운영체제 커널 DLL과, 응용 프로그램들이 생성하는 ‘공유 메모리’(memory mapped file)를 이 영역에다 따로 두고 있다. 물론 NT 계열은 그런 것들도 다 구분 없이 사용자 영역에 저장된다. 실제로는 같은 물리 메모리를 가리키더라도 이를 가리키는 포인터의 값은 프로세스마다 다 다를 수 있다는 것이다. 이런 이유로 인해, 공유 메모리를 생성해 보면 9x 계열은 메모리 위치가 0x80000000을 상회하는 높은 주소인 반면, NT 계열은 심지어 자기 EXE가 로딩된 0x400000보다도 낮은 위치에 매핑이 된 경우도 볼 수 있다.

본인 생각에, 이것은 안정성을 약간 희생하여 좀더 작고 빠른 저사양 친화형 OS를 추구한 9x 계열의 고육지책으로 보인다. 사용자 영역에는 진짜로 각 프로세스마다 따로 돌아가야 하는 메모리만 넣고, 조금이라도 프로세스들이 공유할 여지가 있는 메모리는 여기에다가 따로 옮겨 둔 것이다.
이런 구조상의 차이로 인해 윈도우 9x는 NT 계열만치 커다란 메모리 맵 파일 내지 공유 메모리를 생성할 수 없다. 모든 응용 프로그램들이 1GB짜리 공간 안에서 바둥대며 살아야 하기 때문이다. 하지만 NT 계열은 설령 공유 메모리라 할지라도 마치 자기 개인 메모리 다루듯이 얼추 2GB 안에서 자유롭게 그런 것들을 만들어 보호도 잘 받으면서 쓸 수 있다.

나머지 영역은 전부 커널이 사용한다. 프로세스, 스레드 같은 각종 커널 오브젝트를 생성하고 가상 메모리 내지 페이지 파일들을 관리하기 위한 메모리이다. 쉽게 말해 메모리를 관리하기 위한 메모리. 무슨 커널이 최하 1GB에 넉넉잡아 2GB까지씩이나 주소를 차지하고 있어야 하냐 질문할지 모르는데, 결론부터 말하면 그 정도 공간은 반드시 있어야 하며 사실 2GB조차도 부족한 감이 있다.

NT급 운영체제는 커널 영역의 주소가 사용자 응용 프로그램으로부터 완벽하게 보호받고 있으며 user가 커널 영역 메모리로 접근을 시도하면 즉시 에러가 난다. 둘 사이에 앞서 언급한 "비무장 지대"까지 존재한다. 그러나 9x 계열은 그렇지 못하다.

BYTE *pb = (BYTE *)0xC0001000;
int i;
for(i=0; i<4096; i++) {
        printf("%02X ", *pb), *pb=*pb; pb++;
}

이런 간뎅이-_-가 배 밖에 나온 코드를 실행하면 NT급에서는 당연히 즉시 Access violaton 에러가 나고 프로세스가 사살되는 반면,
9x 계열은 놀랍게도 잘 실행된다. *pb=*pb로 해 줬으니 망정이지 다 0으로 덮어쓴다거나 하면 무슨 일이 벌어질까? 9x 계열이 왜 불안정할 수밖에 없는지 답이 딱 나올 것이다.

같은 32비트 안에서 사용자:커널이 2G:2G가 아니라 사용자한테 좀더 메모리를 많이 줘서 더 대용량의 데이터를 처리할 수 있게 한 3G:1G 부팅 방식도 있긴 한다. 사실 9x 계열도 앞서 말한 구조의 차이 때문에 커널 메모리는 1G이다.
하지만 이 경우 운영체제가 관리할 수 있는 가상 메모리의 이론적 최대치가 크게 감소하고 생성 가능한 커널 오브젝트(프로세스, 스레드, 공유 메모리 등)의 수도 더 줄어든다는 것을 알아야 한다. 또한 응용 프로그램도 large-address-aware하게 빌드되었다는 별도의 플래그가 있어야 한다.

Posted by 사무엘

2010/01/11 00:43 2010/01/11 00:43
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/59

윈도우 API로 다른 프로그램을 "실행", 즉 기술적으로 말하면 프로세스를 생성할 때 쓰는 함수는 크게 다음과 같다.

WinExec, LoadModule, CreateProcess, ShellExecute

어느 것을 사용하더라도 다음과 같은 정보를 받는 란은 꼭 존재한다:
실행 파일 이름, 명령인자, 그리고 메인 윈도우를 표시할 디폴트 방식(SW_SHOW 등).

즉, 윈도우 운영체제는 GUI 기반이라는 특성상 프로그램 메인 윈도우를 기본적으로 최대화하여 실행하라, 창을 숨겨 놓고 실행하라는 식의 지시를 내릴 수 있다. 이런 정보들은 WinMain 함수의 매개변수로 고스란히 그대로 전달된다. 물론 응용 프로그램이 그걸 무시하면 어쩔 수 없지만.

앞의 W..., L... 두 함수는 매개변수가 매우 단순한 편해서 쓰기는 편하나, 16비트 API 시절의 잔재로 치부되어 유니코드 버전조차 존재하지 않으며, 사용이 비추(discourage)되고 있다.

CreateProcess가 32비트 이상급 윈도우 API에서 표준으로 통용되는 가장 원초적인 프로그램 실행 함수이다. 그 대신 받아들이는 매개변수가 무진장 많으며 쓰기가 좀 어렵다. 여기에 대해서는 뒤에서 다시 좀 다루기로 하겠다.

끝으로 ShellExecute는 그 이름이 암시하듯, 커널 계층이 아닌 쉘이라는 꽤 상위 계층에서 구현된 함수로 단순히 파일을 실행하는 게 아니라 인터넷 URL을 기본 웹 브라우저에서 열거나 텍스트 파일을 메모장에서 여는 일도 다 담당한다. 동작 자체도 "open", "print" 등 아예 명령 문자열로 지정할 수 있다. 즉, 쓰임이 훨씬 더 포괄적이다. 이 함수도 EXE를 실행할 때는, 내부적으로 어차피 CreateProcess를 응당 호출한다.

C...는 리턴값이 프로그램의 실행 성공 여부를 나타내는 BOOL 형태인 반면, 나머지 세 함수들은 값이 약간 특이하다. 32보다 큰 정수를 되돌리면 성공을 뜻하고 그렇지 않으면 실패라는 뜻이다.
왜 이렇게 되었냐 하면 이 legacy 함수들은 원래 리턴값이 "인스턴스/모듈 핸들"이었으며 32 이하의 핸들값은 에러를 나타내는 값으로 의미가 예정되었었기 때문이다. 일종의 과거 잔재이다.

오늘날 윈도우 프로그래밍에서 HINSTANCE라고 부르는 핸들은, 과거에는 프로세스 ID와 비슷한 개념이었다. 이 핸들은 자신이 실행한 파일을 식별하는 정보도 있었던지라 동일 EXE를 중복 실행한 것을 WinMain 함수와 함께 넘어온 hPrevInstance로 분간할 수 있었다. 또한 EXE를 실행하여 생긴 인스턴스 핸들과, 그 EXE 안에서 DLL를 읽어들임으로써 이를 식별하는 모듈 핸들(HMODULE)도 별개의 존재였다.

하지만 32비트로 넘어오면서 운영체제의 메모리/파일 관리 모델이 완전히 바뀌었고 오늘날은 HINSTANCE와 HMODULE의 구분이 완전히 없어졌다. 단순히 프로세스 메모리 공간에 맵핑되어 있는 파일 이미지를 가리키는 포인터일 뿐이다. 메모리 영역 overlap에 따른 재배치만 일어나지 않는다면, 해당 DLL/EXE의 preferred base가 그대로 핸들값이 되는 것이다. 인스턴스 핸들이 이렇게 특정 프로세스 안의 주소 공간을 가리키는 포인터가 되는 바람에(national), 이제 이 핸들로 여러 프로세스들을 식별(international)하는 것은 불가능해졌다.

CreateProcess는 사용자가 보내준 파일 + 명령행 사이에다 null 문자를 잠시 삽입하여 토큰화를 했다가, 함수 실행이 끝난 후 문자열을 원래대로 되돌려 준다. C 언어의 strtok 함수를 떠올리면 된다. 이런 이유로 인해 명령행을 넘겨주는 포인터 영역이 read-only const여서는 안 되며 쓰기가 가능해야 한다. (물론 윈도우 NT 계열 운영체제에서 W 버전이 아닌 A 버전을 호출하면 어차피 쓰기 가능한 메모리 버퍼로 인코딩 변환이 일어나기 때문에 read-only 메모리를 넘겨줘도 문제될 건 없다.)

프로그램을 실행할 때는 이 프로그램에다 기본으로 넘겨 줄 각종 환경 변수, 콘솔 프로그램인 경우 표준 입출력 스트림의 핸들, 디버그 실행 여부 등 갖가지 고급 정보를 넘겨줄 수 있으며,
프로그램이 실행되었을 경우 생성된 프로세스의 핸들과 ID 등도 돌려받게 된다. 가령, 이 프로그램이 실행이 완전히 끝날 때까지 내가 기다려야 할 때 이 핸들에 대해 WaitForSingleObject를 호출하고 있으면 된다는 뜻이다. 단, 이 핸들을 Close하는 것도 우리 책임이다.

불필요하게 높은 계층에 자리잡고 있는 ShellExecute 대신, 커널 계층에 있는 CreateProcess를 좀더 간편하게 활용하기 위해 본인은 이 함수를 클래스로 감싸서 쓰고 있다. OpenFileName, TaskDialogIndirect (윈도우 비스타) 같은 복잡한 대화상자 UI 함수만큼이나 CreateProcess도

- 각종 디폴트 argument나 구조체들 챙기기
- 소멸자에서는 결과물로 받은 핸들들 닫아 주기
- 커맨드 라인을 알아서 자체 버퍼에다 생성하고, 필요한 경우 매개변수 전체를 따옴표로 싸 주기
- 이 프로그램의 실행이 끝날 때까지 기다리는 멤버 함수도 추가.

같은 자질구레한 일을 클래스로 감싸 놓으니, 프로그램 실행하기가 한결 편리하다.

Posted by 사무엘

2010/01/11 00:42 2010/01/11 00:42
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/58

※ 1기: 1.x 커널

아래아한글 1.x 시절의 에디팅 엔진입니다. 잘 알다시피 단순한 plain text에다가 약간의 서식만 붙은 것 같은 초보적인 형태였죠.
글씨의 크기 조절은 가로 확대/세로 확대만 되고 가변폭 글꼴은 사실상 지원되지 않았으며, 문단 여백도 그냥 칸 수로 지정하던 시절이었습니다. 표는 선그리기 기능으로 그려야 했습니다.
문서의 파일 포맷은 최소한 1.0, 1.1, 1.2 이렇게 세 방식 이상이 존재했던 것 같습니다. 아래아한글 1.5x는 1.2 방식과 문서 파일 포맷이 동일하며, Alt+V (새 이름으로 저장)를 누르면 과거 1.1 방식으로 저장도 할 수 있습니다.

※ 2기: 2.0 커널

1992년에 출시된 2.0부터 97까지 굉장히 장수하여 안정화한 한컴 2바이트 코드 기반의 에디팅 엔진입니다. 글씨 크기를 포인트로, 여백은 mm 같은 단위로 지정할 수 있게 되고 색깔도 8종류 중 하나로 지정할 수 있게 됐습니다. 가변폭 글꼴의 표현이 가능해지고 그림, 표 같은 각종 개체를 넣을 수 있게 됐습니다. 개요, 스타일 같은 개념도 생겼죠.

문서 파일 포맷은 2.0, 2.1, 3.0으로 나뉩니다. 사실 아래아한글 2.1은 기능면에서는 2.0과 그렇게 큰 차이가 없으나, 글꼴 쪽으로 굉장히 많은 변화가 생겼고 또 2.1에서 문서 압축 저장이 추가됐기 때문에 포맷이 바뀐 것으로 기억합니다. 아래아한글 2.5는 파일 포맷의 변동이 없었기 때문에 2.1과 포맷이 동일합니다.
3.0은 하이퍼텍스트라든가 자체 벡터 드로잉 기능, 그리고 윈도우 OLE 데이터 같은 것을 저장해야 하는 데다, 때마침 2.1 방식 문서 파일의 암호가 크랙되어서 큰 논란을 겪기도 했기 때문에 바뀌었지 싶습니다.

※ 3기: 21세기 커널

정말 많은 우여곡절을 겪은 워디안 때부터 지금까지 큰 변화 없이 이어지고 있는 에디팅 엔진 겸 파일 포맷입니다. 아마 아래아한글은 앞으로 이 방식에서 더 바뀔 일이 없을 것 같습니다.
문자 인코딩이 시대의 조류를 따라 드디어 유니코드로 바뀌고 글씨라든가 용지의 크기 제한이 완전히 사라졌습니다. 색깔도 RGB 어느 색으로나 줄 수 있게 되었으며, 여러 쪽에 걸치는 표처럼 MS 워드의 앞선 기능을 대폭 수용하여 2.0 시절 커널과는 비교가 되지 않는 많은 기능들이 추가됐습니다.

더구나 워디안 이후로 아래아한글은 과거에 없던 여러 기능이 추가되고 있음에도 불구하고 예전과는 달리 파일 포맷의 하위 호환성은 비교적 잘 유지되고 있는 것 역시, 처음에 파일 포맷 설계를 확장성 있게 잘 한 덕택이라고 볼 수 있습니다.
아래아한글도 이제 open xml 기반 문서 파일 포맷도 적극 도입해야 하지 않나 싶습니다만 과연 실현될지?

- MS 워드의 경우 97~2003 커널이 가장 보편적으로 널리 쓰이다가 2007에 와서는 에디팅 엔진과 파일 포맷이 또 크게 바뀌었지요. 95 그 이전 기수는 잘 모르겠네요.
개인적으로 워드보다도 엑셀에서, 편집 가능한 셀 수가 크게 증가하고 색깔 제한이 없어진 것을 매우 환영합니다.

Posted by 사무엘

2010/01/11 00:37 2010/01/11 00:37
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/56

한메 타자 교사(HTT).
정말 전설적인 타자 연습 프로그램이며, 이후에 등장한 동일 분야 프로그램들의 근간을 제공했습니다.

아래아한글 1.x와 비슷한 연배의 프로그램이죠. 90년대 초반에 개발된 도스용 응용 프로그램들이 90% 이상 볼랜드 터보 C 2.0 기반이었고 그래픽 모드 동작을 위해 BGI 라이브러리를 사용한 것과는 대조적으로 HTT는 MS C 6.0 기반입니다. (비주얼 C++ 6.0이 아님!)

  당시에 통용되던 프로그램들을 좀더 살펴보면,
페르시아의 왕자도 1, 2 모두 MS C로 개발되었고 볼랜드 계열 빌드가 아닙니다.
아래아한글은 16비트 바이너리들은 전통적으로 볼랜드 컴파일러를 써 왔지만, BGI 라이브러리 기반은 물론 아니지요.

HTT는 제가 두벌식을 쓰던 시절과 맥을 함께 했습니다. 세벌식 연습은 도스용 한컴 타자 연습으로 주로 했고 HTT를 쓰지 않았거든요. 390에서 최종으로 갈아타던 시절에는 박 정만 님이 개발한 <광타>의 도움을 받기도 했습니다. 그때가 얼마나 불모지였냐 하면 390 말고 최종 연습을 정식으로 지원하는 프로그램이 “없었습니다.” 윈도우 운영체제는 말할 것도 없고 아래아한글 97이 제공하던 최종 자판에도 오류가 있었습니다. 지금이야 워디안 때부터 최종 자판이 제대로 지원되기 시작했고, 윈도우용 한컴 타자 연습에도 최종 배열이 추가되긴 했지만, <날개셋> 타자연습이 첫 등장하던 시절엔 정말 제 프로그램의 지위가 더욱 독보적이었었습니다.

한메 타자는 일부러 이렇게 만들기라도 했는지 문장 연습하는 감이 묘하게 좀 좋지 않았습니다. 키를 계속 누르고 있으면 글자가 생기는 느낌이 더디고 좀 latency가 느껴집니다. 아마 이것 때문에 그 당시 세벌식 연습을 한메 대신 한컴으로 사용하지 않았던가 생각됩니다.

두벌식으로는 단문도 700 이상은 정말 무리였지만 지금 세벌식으로 연습해 보니 800 넘는 것도 가뿐하군요. “드는 정은 몰라도 나는 정은 안다.”라는 문장은 완전 세벌식 최적화 문장이어서 1000을 넘기기도 했습니다.

그리고 베네치아 게임을 오랜만에 해 보니,
<날개셋> 타자 게임의 혹독하기 그지없는-_- 지옥 훈련에 단련돼 있는 저한테는 정말 애들 장난도 아니었습니다. 떨어지는 속도도 느리고 단어도 훨씬 더 짧고 쉬운 것들이고..!
1단계부터 시작해 보니 2만점대의 점수로 끝탄을 깼습니다. 껑충 바이러스가 두 번이나 걸렸습니다.

8단계부터 시작하니 클리어 시 보너스가 더욱 붙어 47000점대의 점수를 획득했습니다. 물론 단 한 번도 HP를 소모한 적이 없었으므로 재건 바이러스는 아무 의미가 없었죠.

<날개셋> 타자연습의 게임은 베네치아를 전혀 어려움 없이 가뿐하게 엔딩 보는 개발자 본인도 만신창이로 간신히 다 클리어할 정도로 월등히 더 어렵게 짜여 있습니다. 옛날 버전은 지금보다도 더 어려웠어요. -_-;; 난이도와 각종 주인공 밸런스들은 거의 05~06년 이후로는 더 수정 없이 완전히 정착한 듯합니다. 지금 이 상태가 딱 적당하며, 더 어렵게도, 더 쉽게도 만들 필요 없을 것 같습니다. 지금은 타자를 치는 인구가 훨씬 더 늘었으니 국민 평균 실력도 영어 실력만큼이나 더욱 상향 평준화해 있을 거라는 점, 모아치기 같은 세벌식 고급 입력 기능을 십분 활용할 수 있다는 점을 감안하면 말이죠.

옛날에 두벌식 쓰던 시절엔 베네치아도 6~8단계 정도만 되면 글자 떨어지는 게 무서워서 차마 못 할 정도였는데 정말 격세지감입니다. 그나저나 “에이즈 바이러스 퇴치!”와 “지뢰 바이러스”는 도대체 뭘 하는 놈이고 왜 넣었는지 모르겠습니다. 전자는 아무 효과 없는 꽝인 것 같고, 후자는 글자들이 지뢰에 부딪히면 점수가 깎이는 것 정도밖에 모르겠네요.

<날개셋> 타자연습 1.x를 개발하던 초창기 시절엔 한메, 한컴, 광타는 물론이고 신의 손, 번개손, 천타를 꿈꾸며 같은 당대의 경쟁(?) 프로그램들을 많이 참고했습니다. 개인적으로는 도스용 <신의 손>이 정말 완성도가 높다고 인정하며, 그 열악한 640*480 16컬러에서 어지간한 게임을 방불케 하는 비주얼 디자인을 연출해 낸 것에 최고의 점수를 주고 싶습니다. 게임도 나름 테마를 갖춰서 무척 잘 만들었죠.

아무튼, 한메 타자 연습을 보니 이런 저런 여러 생각이 들었답니다. 그리고 세벌식 만세입니다. =_=;;;

Posted by 사무엘

2010/01/11 00:35 2010/01/11 00:35
, ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/55

한자파들의 패턴

- 한글 전용에 반대하고 학교에서 한자 교육을 더 일찍 더 많이 더 강화하는 걸 좋아한다.
- 각종 안내 표지판이나 공문서 같은 곳에서 한자를 더 많이 볼 수 있게 되는 걸 좋아한다.

- 한글 풀어쓰기를 극렬 반대하고 배척한다.
- 그들에게 한글과 한자는 수레의 양 날개이다.
- 중국· 일본의 지명/인명을 현지음으로 읽는 걸 극악으로 혐오한다. (북경 > 베이징, 모택동 > 마오 쩌둥)
- 띄어쓰기를 싫어하며 어지간한 복합 명사들은 붙이는 걸 선호한다.
- 세로쓰기에 굉장히 우호적이다.
- 중국, 일본 사람과의 필담(?)을 엄청 좋아하며 한중일 한자 일치 사업에 우호적이다.

- 영어, 알파벳 남발을 싫어한다. 거기까지는 좋은데 요즘 그렇게 돼 가는 원인이 한자를 안 가르쳤기 때문이라고 생각한다. -_-;;
- 오늘날 문화가 저질화하고 어휘력/사고력/학력 저하 따위가 한글 전용 때문이라고 생각한다. 일각에서는 심지어 좌경화까지 한글 전용 탓으로 돌린다.

- 부모님 이름을 한자로 못 쓰는 건 정말 치욕적인 불효이다.

* * * * * *
그 반면, '한글' 진영 안에서 보편적으로 통용되는 신념은..

- 한자 교육은 현행처럼 중학교부터 가르치는 거나 똑바로 잘 하면 충분하다고 여긴다.
- 한글 전용법의 '얼마 동안을' 조항마저도 이제 삭제해야 한다고 여긴다.
- 풀어쓰기는 주류가 되기는 곤란하나 특수한 분야의 연구 주제로 가치 정도는 인정한다.

- 한글 하나만으로 충분하며 한자는 말 그대로 얼마든지 우리 마음대로 처분해도 되는 낡은 유물(legacy)일 뿐이다.
- 언어에는 청각성이 배제되어서는 안 됨을 인지하며 불필요한 한자어 남발을 자제한다.
- 한자 문화권 국가라도 가능한 한 현지음 표기를 존중해야 한다고 여긴다.
- 엄밀한 맞춤법과 띄어쓰기를 추구하여 한글 자체를 '표의성'을 지닌 표음문자로 활용하려 노력한다.
- 가로쓰기, 탈네모꼴 글꼴 같은 쪽에 우호적이다.

- 한중일은 한자 안에서도 말과 글이 서로 다 달라져 있기 때문에 글자 일치 사업에 거의 의미를 두지 않는다.

Posted by 사무엘

2010/01/11 00:33 2010/01/11 00:33
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/53

우주 쓰레기

http://www.hani.co.kr/arti/science/kistiscience/336364.html
http://pc21th.egloos.com/4496840
(참고)

철도는 선로 위의 돌멩이가 치명적인 약점이고
항공기는 조류 충돌이 치명적인 약점이라면
인공 위성, 우주 왕복선 등에는 지구 표면을 뒤덮고 있는 수천, 수만 개의 우주 쓰레기들이 치명적인 위협으로 작용하고 있습니다.

5, 60년대 처음 발사되던 당시에 인공 위성은 인류에게 우주 개발 시대를 여는 신호탄이었고, 미국· 러시아 같은 강대국의 최첨단 과학 기술의 총아였습니다.
지구는 둥글기 때문에 직진하는 전파만으로는 지구 반대편으로 신호를 보낼 수 없습니다. 과거에는 고맙게도 지구 대기권의 전리층이 전파를 반사해 주었기 때문에 어느 정도 무선 통신이 가능했습니다.

하지만 오늘날처럼 정보가 폭증하고 있고 옛날보다 훨씬 더 파장이 짧은 전파도 쏘아올리는 시대에는, 지구 전리층만으로는 한계가 있고 통신 위성이 전파를 별도로 처리해 주어야 합니다. 달에는 전리층 같은 것도 없기 때문에 달 뒷면에 쏙 숨으면 지구와 교신이 그대로 끊어져 버립니다. 놀랍죠?

위성은 말 그대로 한없이 지구를 향해 떨어지고 있는 덕분에 지구상에 떠 있는 존재입니다. 통신 용도로 쓰이며 지구 자전 주기와 공전 주기가 완전히 같은 '정지 위성'은 지표면으로부터 무려 35000km에 달하는 곳에 떠 있으며, 개수도 전세계적으로 200개가 채 되지 않습니다. 이 이상은 더 띄우지 않기로 국제 협약까지 맺어져 있습니다.

하지만 이보다 더 낮은 고도, 짧게는 300~2000km 정도의 고도에서 도는 인공 위성도 굉장히 많이 존재합니다. (이 정도만으로도 이미 최소한 열권 이상이고 우주나 다름없는 영역입니다) 그리고 이 저궤도 위성이 문제입니다.

낮은 궤도를 도는 위성은 그만큼 지표면과 가깝기 때문에 통신이나 정찰 임무를 더 원활히 수행할 수 있으며 띄우는 데 드는 비용도 저렴합니다. 그렇지만 그만큼 대기와의 마찰도 고궤도보다는 커서 계속 떠 있기가 힘들며, 지구를 매우 빠르게 돌아야 합니다. 공전 횟수가 하루에 10수 회 정도는 기본인 걸로 알고 있습니다.

이런 이유로 인해 저궤도 위성은 수명이 짧습니다. 열권 정도만 돼도 위성은 잘 알다시피 태양 방면과 지구 방면의 표면 온도차는 달의 낮과 밤의 차이만큼이나 벌어집니다. 위성은 이런 환경에서도 자체적으로 열 제어를 하고, 마치 통닭구이처럼 뱅글뱅글 돌면서 온도 배분을 균형 있게 하도록 설계되지요. 지표면보다 훨씬 더 열악하고 살벌한 환경에서 동작하는 기계인 것입니다. 거기에 돌아가는 컴퓨터도 오늘날의 PC에다 견주자면 XT급이 될까말까 하지만 그걸로도 옛날에는 임무 수행 할 걸 다 한 셈입니다.

하지만 수명이 다하고 이물질 때문에, 혹은 초속 수십 km로 날면서 공기와의 마찰이 누적되어 야기된 물리적 손상 때문에, 제품에 미묘한 오동작이 발생하면.. 이런 균형이 깨지게 됩니다. 위성은 이 온도차를 견디지 못하고 단순히 고장나서 작동만 중단되는 게 아니라 배터리 같은 것이 열받아서 펑 폭발합니다.

수명이 끝난 폐 인공 위성이라든가 이런 잔해들은 땅에 잘 떨어지지도 않고 초속 수~수십 km로.. 총알보다도 더 빠른 속도로 날아다니면서 우주 교통을 방해하는 요인이 되고 있으며, 인공 위성의 추후 발사를 어렵게 만들고 있습니다. 말 그대로 우주 쓰레기들입니다. 부딪치면 꽤 많이 아플 겁니다. 이 정도면 조류 충돌쯤은 저리가라이죠?

인공 위성 잔해는 아니지만, 로켓이 발사되면서 떨어뜨린 수백 kg급의 연료 탱크가 바닷속에 처박히지도 않고 우주 쓰레기가 되어 지구 주변을 돌고 있었다는 말에도 적지 않은 충격.
인간의 손길이 닿은 곳은 땅, 물, 공기도 모자라서 우주 공간까지 자가 회수가 되지 않는 폐기물 찌꺼기들로 몸살을 앓게 되는 것 같습니다. 무슨 일을 해도 깔끔하게 하질 못하고 꼭 side effect를 남기고, 뒷수습을 스스로 못 합니다.

이런 우주 쓰레기들은 컴퓨터로 비유하자면 garbage collection 없이 memory leak가 한계에 달하고 있는 컴퓨터 메모리라든가, 수천 개의 legacy들과 DLL hell로 몸살을 앓고 있는 과거 윈도우 시스템 디렉터리를 보는 것과 같습니다.

Posted by 사무엘

2010/01/11 00:31 2010/01/11 00:31
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/52

자동차가 다니는 도로 중에는 일반 시가지의 도로와는 달리, 진출입로를 입체화하여 신호 대기를 없애고 보행자는 물론 이륜차도 접근할 수 없게 한 ‘자동차 전용’ 도로가 있다. 이런 도로는 최고 속도 제한뿐만 아니라 최저 속도 제한까지 있어 많은 자동차가 원활하게 통과하도록 하고 있다.

한편, 도시와 도시를 이으며 해당 지역이 아닌 중앙 정부에서 노선을 직접 고시하여 관리하는 도로를 ‘국도’라고 부른다. 국도는 이미 번호로 매겨져 있어서 가령 1번 국도는 서울, 안양, 평택 등 처음엔 경부선 철도와 비슷한 길을 가다가 목포로 가며, 4번 국도는 경주 감포에서 출발하여 대전까지 경부선과 비슷한 방향을 향하다가 당진에서 끝난다. 국도라는 용어에는 시설이라는 개념은 그다지 들어있지 않기 때문에, 심지어 비포장 아니면 2차선 도로일 수도 있고 최근에 리모델링된 국도 구간은 미국 프리웨이급의 8차선의 고가 도로일 수도 있다. 원래 국도의 노선은 북한 지역까지 다 포함하고 있다.

이 글에서 다루고자 하는 한국의 고속도로는 자동차 전용 도로의 성격에 가깝지만 행정상으로는 ‘고속 국도’이다. 즉 국도이지만 통행료를 받는 유료 도로이고 시설이 일반 국도보다 훨씬 더 좋다. (88올림픽 고속도로는 예외이지만.)
사실 이런 고속도로와 개념적으로 정확하게 100% 대응하는 말이 영어에는 존재하지 않는다. 미국에는 한국의 경부 고속도로급의 넓고 잘 뻗은 길이 경부-경인 축이나 수도권에만 있는 게 아니라 미국 전역에 구축되어 있다. 하지만 한국과 같은 유료 도로는 아니다.

고속도로가 많지 않던 시절에는 매 도로마다 이름이 붙어 있었지만 요즘은 고속도로가 워낙 거미줄처럼 많이 놓이고 구조가 복잡해지면서, 우리나라도 고속도로의 이름을 없애고 일반 국도처럼 번호만으로 부르려고 시도하고 있다. (한국의 고속도로로서 상징적인 의미가 매우 큰 경부 고속도로는 당당히 1번이다.)
하지만 국민 정서상 그게 금방 정착할 것 같지는 않다. 주변에는 여전히 경부, 중부내륙, 영동 같은 명칭이 친숙하다.

이 한국의 고속도로는 유료 도로이다 보니 통행료를 징수하는 톨게이트가 존재한다. 마치 지하철 역 내부가 승차권 개집표기 전후로 분리되어 있고, 공항 내부가 탑승권 소지자만 들어가는 구역으로 분리되어 있는 것처럼 고속도로 구간을 분리하는 역할을 톨게이트가 하는 셈이다. 톨게이트는 차량의 소통을 크게 방해하기 때문에 이 오버헤드를 줄이고자 요즘은 하이패스 같은 기술이 등장하기도 했다.

톨게이트는 고속도로가 시작하는 양 종점에 있고 또 각 지역 인터체인지 말단에도 있다. 그래서 자동차는 톨게이트를 통과하여 고속도로에 진입한 후 톨게이트를 통과하여 고속도로에서 벗어나게 된다. 여기까지는 이해하는 데 아무 어려움이 없을 것이다.

그런데 경인이나 외곽 순환 같은 수도권 고속도로에서는 얘기가 좀 달라진다. 여기서는 단순히 장거리 여행이 아니라 매일 출퇴근을 고속도로로 하는 사람도 굉장히 많다. 진출입로인 인터체인지도 훨씬 더 조밀하게 많이 있다. 마치 일반 철도역 간격으로 있던 역이 (광역)전철역 간격으로 바뀌는 것과 정확히 같다. 여기에 일일이 다 톨게이트를 설치하고 수많은 차들을 세우는 것은 현실적으로 무리이다.

그렇기 때문에 이 두 고속도로는 다른 방법으로 통행료를 징수하고 있다.
일단 고속도로에 진입 자체는 톨게이트 없이 마음대로 한다. 하지만 도로 중간중간에 톨게이트가 있다. 외곽 순환의 경우 전구간을 통틀어 6개의 톨게이트가 있으며 경인 고속도로는 도로 중앙에 톨게이트가 하나 있다. 물론 통행료도 일반적인 거리 비례제가 아니라 고정된 요금을 매우 조금만 징수한다. 또한 톨게이트를 통과하지 않는 구간만 이용할 때는 통행료를 낼 필요가 없다.

따라서 경기도 남부에서 수평축의 외곽 순환 고속도로와 만나는 수직축의 서해안/경부/중부 고속도로들은, 외곽 순환 고속도로와 만나기 전에 이미 전통적인 방식의 요금 정산과 징수를 끝내야 한다. 그래서 제각기 서서울/서울/동서울 톨게이트는 안산, 성남 같은 꽤 남쪽에 자리잡고 있다.

철도뿐만 아니라 도로도 수도권과 비수도권이 상이한 교통 수요에 따른 상이한 운영 방식을 유지하고 있다는 것을 알 수 있다.

참고로, 철도는 서울을 기점으로 보지만 도로는 남북 통일과 대륙 진출을 염두에 두고 남쪽을 기점으로 보고 있다는 것이 흥미로울 것이다. 즉 경부 고속도로의 기점을 서울이 아닌 부산으로 본다는 것이다.

Posted by 사무엘

2010/01/11 00:28 2010/01/11 00:28
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/51

class CAppFrame: public CWnd {
public:
        void PostNcDestroy() { delete this; }
};

class CMyApp: public CWinApp {
public:
        BOOL InitInstance();
};

CMyApp g_App;

BOOL CMyApp::InitInstance()
{
        m_pMainWnd=new CAppFrame;
        m_pMainWnd->CreateEx(0, AfxRegisterWndClass(0), _T("Hello World"), WS_OVERLAPPEDWINDOW,
                100, 100, 500, 500, NULL, NULL);
        m_pMainWnd->ShowWindow(SW_SHOW);
        m_pMainWnd->UpdateWindow();
        return TRUE;
}

위의 코드는 MFC를 써서 만들 수 있는 가장 간단한 GUI 프로그램이다. 빈 창만 달랑 뜨는 게 허전하면, message map 넣고 OnPaint에다가 Hello, world! 출력하는 코드만 추가해 주면 된다.
MFC로 창을 띄우기 위해서는 본질적인 것 딱 두 가지만 기억하면 된다.

첫째, CWnd에서 상속 받은 클래스를 만들기

둘째, CWinApp에서 상속 하나 받아서 전역 개체를 하나 반드시 만들고, InitInstance를 오버라이드하여 내 윈도우 클래스를 생성하는 코드를 짜 주기

물론 요즘은 닷넷 프레임워크 같은 더 객체 지향적이고 깔끔한 API도 나와는 있지만 저 정도만 해도 그냥 C언어 + Win32 API만 썼을 때와는 비교할 수도 없이 간단하게 내가 원하는 일을 곧장 시작할 수 있다. 윈도우 클래스 등록, 윈도우 프로시저 등 온갖 지저분한 내부 처리를 상당 부분 MFC가 알아서 해 주기 때문이다.

MFC의 핵심부이며 가장 자주 다루게 되는 부분은 역시 윈도우를 나타내는 CWnd 관련 개체이다. 응용 프로그램의 메인 윈도우부터 시작해서 대화상자와 대화상자 안의 자그마한 컨트롤까지 매우 다양한 용도로 쓰이는 HWND를 한 뿌리 클래스와 상속 클래스만으로 원활히 제어하기 위해 MFC는 굉장히 심도 있게 설계되었으며 내부적으로 자질구레한 일들을 매우 많이 해 주고 있다. 단순히 ShowWindow(hWnd, SW_SHOW)를 wnd.ShowWindow(SW_SHOW)로 바꿔 주는 것을 훨씬 넘어서는 수준이다.

더구나 메시지 맵을 통해 컨트롤 서브클래싱(기존 윈도우 컨트롤의 동작을 부분적으로 조작하는 것)까지 매끄럽게 연결시킨 것까지 보면, 솔직히 굉장히 잘 만든 프레임워크임을 인정하지 않을 수 없다.

이런 프레임워크를 만들 때 근본적으로 문제가 되는 것은 CWnd라는 C++ 오브젝트와 운영체제의 HWND 사이의 씽크를 맞춰 주는 작업이다. 둘은 원래 개념적으로 생성 주기나 scope이 서로 완전히 다른 존재이다. 하지만 MFC는 한 HWND를 가리키는 CWnd 오브젝트가 중첩되지 않도록 배려하고 있으며, 나의 C++ 코드에 의해 생성되지 않은 외부 HWND에 대해서도 임시 맵까지 만들어 가면서 CWnd를 동기화해 주고 있다. 멀티스레드 환경까지 감안하면 이는 더욱 복잡한 작업이 된다.

new 연산자로 CWnd가 생성될 때 CreateWindow를 같이 해 주고, HWND가 완전히 소멸되어 WM_NCDESTROY가 왔을 때 CWnd까지 delete로 지워 주는 것은 대부분의 경우엔 바람직한 디자인 패턴이나, 이것이 언제나 유용한 것은 아니다. 가령 modal 대화상자는 자체적으로 message loop까지 갖추고 있기 때문에 heap이 아닌 스택에다가 간단히 지역변수로 선언하는 경우가 더 유용하기 때문이다. 더구나 대화상자는 사용자가 대화상자를 닫았더라도, 이 C++ 클래스 갖고 있는 데이터 변수들을 후에 활용하는 경우가 많기 때문에 HWND 개체가 사라진 뒤라도 C++ 개체는 남아 있어 줘야 한다.

이래저래 CWnd와 HWND 사이의 관계와 생성/소멸 주기는 여러 모로 이해하기 까다롭다. CWnd 클래스 중에서 new로 생성되고 HWND의 소멸과 동시에 소멸되어야 하는 오브젝트라면, PostNcDestroy 함수를 오버라이드하여 delete this를 넣어 주어야 메모리 누수가 발생하지 않는다. 응용 프로그램의 주 프레임 윈도우라든가 modeless 대화상자가 이런 예에 속한다.

저 소스 코드에서는 CWnd를 날것으로 사용했지만, CWnd에서 파생되어 아예 전문적으로 응용 프로그램의 주 프레임 윈도우를 담당하고 있는 MFC 클래스인 CFrameWnd는 PostNcDestroy가 이미 저렇게 구현되어 있다. 그뿐만 아니라 이 클래스는 LoadFrame 함수에서 이미 윈도우 클래스의 등록까지 다 알아서 해 주기 때문에 저 소스 코드에서처럼 AfxRegisterWndClass를 번거롭게 호출할 필요도 없다. 사용자가 준 ID와 일치하는 응용 프로그램 타이틀, 아이콘, 심지어 단축키 액셀러레이터 테이블 따위를 모두 엮어서 윈도우의 기반을 자동으로 구성해 주기 때문이다.

MFC를 써서 아주 간단한 프로그램을 짜고 싶은데 비주얼 C++의 MFC 마법사가 기본으로 생성해 주는 코드는 군더더기가 너무 많다. 그래서 이럴 때 본인은 MFC 없이 일반 Win32 응용 프로그램으로 프로젝트를 시작한 후, 저 코드 템플릿을 갖다 붙이고 프로젝트 세팅을 “MFC 사용”으로 수동으로 바꾸는 방법을 쓴다.

필요한 건 MFC가 잘 캡슐화해 준 message loop, 몇몇 GDI 오브젝트 같은 것밖에 없는데 이것만 쓰기에는 MFC는 덩치가 너무 커지고 static link를 하기에도 오버헤드가 너무 큰 것도 불만이다. 차라리 known DLL만 쓰기 때문에 매우 가벼운 바이너리를 만들 수 있는 비주얼 C++ 6.0이 그리울 때도 있다. 어차피 이후 버전에서 추가된 기능은 거의 안 쓰기 때문에.

<날개셋> 타자연습은 소스를 보면 알겠지만 딱 MFC를 써서 개발되었다. 하지만 한글 입력기는 3.0부터 MFC를 쓰지 않으며, 믿거나 말거나 MFC를 어설프게 흉내 내어 본인이 내부적으로 자체 개발한 프레임워크 라이브러리를 static link하여 개발해 오고 있다. 하지만 자체 라이브러리는 오버헤드 줄이고 최대한 가볍게 만드느라, Win32 API라든가 각종 핸들을 캡슐화한 수준이 MFC 수준으로 범용적이고 체계적이고 편하지는 못하기 때문에, 여전히 MFC가 그리울 때가 있다. ^^;;

Posted by 사무엘

2010/01/11 00:27 2010/01/11 00:27
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/50

« Previous : 1 : ... 221 : 222 : 223 : 224 : 225 : 226 : 227 : 228 : 229 : ... 230 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2026/07   »
      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 31  

Site Stats

Total hits:
3940764
Today:
1432
Yesterday:
2118