16비트 시절에는 잘 알다시피 int 포함 machine word의 크기가 말 그대로 2바이트였다. 그리고 근거리/원거리 포인터가 존재했으며 복잡한 메모리 모델을 따져야 했다. 여기까지는 도스든 윈도든 공통이다. 그럼, 그 시절에 Windows 프로그래밍은 어떠했을까?

16비트 Windows는 잘 알다시피 모든 프로그램이 단일 스레드를 공유하면서 단일 메모리 주소 공간에서 실행되었다. 이런 열악한 환경에서 멀티태스킹을 구현하는 것은 결코 쉬운 일이 아니었다.
그래서 그 시절에는 콜백 함수를 운영체제에다 지정해 주는 것조차도 보통일이 아니었다. 오늘은 오랜만에 이 부분에 대해서 예전에 몰랐다가 최근에 본인이 추가로 알게 된 이야기를 좀 하겠다.

Windows API는 C언어 함수 형태로 만들어졌으니 그때는 지금으로 치면 C++ 가상 함수가 할 일을 함수 포인터로 다 처리하고 있었다. 윈도우 프로시저, 대화상자 프로시저 같은 것 말이다.

그런데 같은 프로그램이 두 번 중첩 실행되면, 코드는 동일하더라도 그 코드가 다루는 스택(데이터) context는 결국 프로세스별로 서로 달라질 수 있게 된다. 이를 어떻게 구분해야 할까?
32비트 이후부터는 가상 메모리 기술이 워낙 발달하여 그 context가 CPU 차원에서 알아서 따로 잘 처리된다. 그러나 16비트 기계엔 그런 개념이 없었다.

결국은, 실제 콜백 함수가 호출되기 전에 그 콜백 함수가 처리할 자신의 데이터 세그먼트 영역을 CPU 레지스터에다 써 주는 stub, 일명 썽킹(thunking) 코드를 소프트웨어적으로 별도로 만들어야 했다. C++로 치면, 클래스 멤버 함수 호출을 위해 this 포인터의 값을 EAX 레지스터에다 써 주는 것과 개념적으로 비슷하다.

우리가 만든 콜백 함수는 그 썽킹 함수를 통해서 호출해야 한 것이다. 운영체제에다가도 당연히 썽킹 함수를 알려 주고 말이다.
이것이 바로 16비트 시절 코드를 보면 밥 먹듯이 보이는 MakeProcInstance와 FreeProcInstance API 함수의 정체이다.
별도의 메모리를 추가로 할당해서 기계어 코드를 추가해 준 것이기 때문에, 메모리의 해제까지 해 줘야 한다.

대화상자 하나를 출력하더라도 아래처럼 말이다.

FARPROC pfnThunkProc = MakeProcInstance( (FARPROC)My_Actual_Dialog_Proc, hInstance); //내 대화상자 프로시저가 우리 인스턴스 핸들을 context로 동작하게 한다
DialogBox(hInstance, "Dialog_Resource_Name", hWndParent, (DLGPROC)pfnThunkProc );
FreeProcInstance(pfnThunkProc);

요즘 같으면 아래의 절차 하나만으로도 충분했을 텐데 말이다.

DialogBox(hInstance, "Dialog_Resource_Name", hWndParent, My_Actual_Dialog_Proc );

결국 My_Actual_Dialog_Proc라는 코드는 시스템 전체를 통틀어서 단 하나 유일하게 존재하겠지만,
이 프로그램을 여러 번 실행하더라도 각 프로그램들은 그 함수로부터 파생된 자신만의 고유한 콜백 함수를 통해서 대화상자를 호출하게 된다.

단, Windows 3.1에서는 함수명을 export해 주는 것만으로 이렇게 콜백 함수에 대한 썽킹을 매번 해 줘야 하는 번거로움을 생략할 수 있었다고 한다.

지금이야 프로그래밍에서 export 키워드라 하면, C++에서 템플릿의 선언과 정의를 번역 단위를 넘나들며 공유할 수 있게 하려 했던 비현실적인 흑역사 키워드일 뿐이다. Windows 플랫폼으로 문맥을 넓힐 경우, export는 클래스나 함수 심벌을 빌드되는 파일 차원에서 외부로 노출하여 GetProcAddress 함수로 노출이 되게 하는 속성 지정자이다. 비주얼 C++ 기준으로 __declspec(dllexport) 라고 쓴다.

지금이야 이런 export 속성은 말 그대로 DLL을 만들 때에나 쓰인다.
그러나 16비트 시절에는 EXE도 운영체제로부터 호출을 받아야 하는 콜백 함수를 넘겨 줄 목적으로 심벌 export를 즐겨 활용했었다.
export된 함수는 외부로부터 호출받는 게 당연시될 거라 여겨졌으므로, 링커와 운영체제가 자체적으로 데이터 세그먼트 보정을 하는 전처리 루틴을 추가해 줬다. 따라서 코드가 훨씬 더 깔끔해진다.

이런 이유로 인해 Windows 3.x 실행 파일들을 헥스 에디터로 들여다보면 대체로 ...WNDPROC, ...DLGPROC 같은 식으로 끝나는 웬 이상한 함수 이름들이 내부에 들어있는 걸 확인할 수 있다. 32비트 이후부터는 찾을 수 없는 관행이다. 자기 내부에서만 쓰는 콜백 함수들을 왜 저렇게 노출해 놓겠는가?

어떤 함수에 export 속성을 부여하기 위해서는 결국 C/C++ 언어에다가 없는 문법을 새로 추가하거나, 아니면 소스 코드는 그대로 놔 두고 컴파일러가 아닌 링커만이 인식하는 부가 정보 같은 게 주어져야 할 것이다. 전자는 소스 코드의 이식성을 떨어뜨린다는 부담이 있지만, 그래도 뒤끝이 없고 한 소스에 빌드에 필요한 모든 정보가 한데 모이니 편리하다. 그래서 그 당시에는 __export라는 비표준 MS 확장 키워드가 도입되었고, 이를 보통 EXPORT라는 매크로로 감싸서 사용하곤 했다. 이런 식으로 말이다.

long FAR PASCAL EXPORT MyWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam); //그 당시 콜백 함수는 반드시 '파스칼' 방식이라는 함수 호출 규약대로 선언되어야만 했다.

한편 후자는 바로 그 이름도 유명한 DEF(모듈 정의) 파일이다.
지금도 DEF 파일이 안 쓰이는 건 아니지만 정말 DLL을 만들 때가 고작이다. 그 반면 16비트 시절에는 DEF가 훨씬 더 중요하게 쓰였던 모양이다.
export하는 콜백 함수뿐만 아니라 이 프로그램에 대한 소개문, 그리고 필요한 스택/힙 크기까지 정확하게 명시되어야 했다.

32비트 이후부터는 스택/힙이 부족하면, 프로그램 로딩 시간이 좀 더 걸릴 뿐이지 실시간으로 추가 할당하여 working set의 확장이 가능한 반면, 16비트 시절에는 메모리 양도 부족하고 또 한 주소 공간에서 여러 프로그램들이 뽁짝뽁짝 복잡하게 지내다 보니 이런 게 핀트가 어긋나면 프로그램 실행이 아예 불가능했을 것 같다.

옛날의 New Executable 포맷에는 자체적으로 name table이라 불리는 범용적인 문자열 테이블이 있었고, import/export하는 심벌 이름은 물론 이 EXE/DLL에 대한 간단한 소개문까지 그런 데에 들어갈 수 있었다.
지금으로 치면 버전 리소스에 들어가는 description과 유사한데 역할 중복인 셈이다. 그런 것까지 DEF 파일에다 명시해 줬었다.

자.. 설명을 들으니 어떤 생각이 드시는지?
16비트 Windows용 실행 파일을 분석하는 도구는 그리 충분치 않다. 일단 개발자들의 친구인 Dependency Walker가 이를 전혀 지원하지 않으며, 그나마 괜찮은 물건으로는 옛날에 Windows 98에 내장되어 있던 QuickView라는 프로그램이 적격이었다. 기본적인 사항은 다 잘 출력해 줬다.

16비트 시절에는 잘 알다시피 HINSTANCE는 각 프로그램의 데이터 세그먼트를 식별하는 번호표에 가까웠고, 개념적으로 지금 같은 포인터가 아니라 오늘날로 치면 오히려 프로세스를 식별하는 HANDLE처럼 널리 쓰였다. (비록 Close를 할 일은 없었겠지만 말이다) 게다가 EXE는 HINSTANCE, DLL은 HMODULE로 성격도 달랐다. 그래서 LoadLibrary 함수의 리턴값은 분명 HMODULE이다.

그때는 EXE/DLL로부터 리소스를 얻어 오는 과정도 정말 복잡했고 Load/Free 절차뿐만 아니라 lock/unlock까지 있었다. 메모리의 절대적인 양이 충분치 않기도 하고 가상 메모리 같은 시스템이 없던 관계로, 단편화를 방지하기 위해 평소에 즉각 쓰지 않는 메모리 블록은 재배치가 가능하게 놔 두는 관행이 더 보편적이었기 때문이다.

한편으로 그때는 시스템 전체에 영향을 끼치기가 쉬웠다. 특히 DLL이 이 분야에 관한 한 지존이었다.
DLL에서 선언한 전역변수는 모든 프로세스가 한데 공유되었으며, DLL이 실행하는 코드는 저런 EXE처럼 여러 컨텍스트에서 중첩 실행될 일이 없고 애초에 데이터 세그먼트 구분을 할 필요가 없었다!

그리고 16비트 시절엔 애초에 콜백 함수를 지정해 주는 과정이 처음부터 저렇게 번거로웠던 만큼, 시스템 전체의 동작 방식을 바꾸는 global 훅을 설치하더라도 훅 프로시저를 반드시 DLL에다가만 만들어야 한다는 제약이 없었다.
그럼에도 불구하고 16비트 시절은 32비트 시절보다 편한 것보다는 불편한게 더 많았다는 것이 부인할 수 없는 사실이다.

끝으로 여담.
이렇듯, 본인은 초등학교 아주 어릴 적부터 프로그래밍을 시작한 관계로, 그 시절에 대한 향수가 있고 '레트로'-_- 컴퓨팅 쪽으로 관심이 많다.
그런데, 그런 것에서조차도 양덕후들의 기상은 갑이다. the old new things 같은 블로그는 이 바닥의 지존이라고 봐야 하고, Windows 3.x로도 모자라서 2.x나 1.x용 프로그램을 만들었다고 인증샷 올리는 사람도 있다.

1985년에 출시된 Windows 1.x의 경우, VGA 카드조차도 없던 시절에 만들어진 관계로 가장 좋은 비디오 모드가 640*350 해상도짜리 EGA이다. 그런데 그걸 640*480 VGA 내지 심지어 800*600 SVGA에서 동작하게 드라이버 패치를 만든 사람도 있다.

참고로 Windows 1.x 정도 되면.. 프로그램 개발을 위한 컴파일러는 그야말로 1986년에 나온 MS C 4.x를 써야 하고, 얘는 함수 호출 인자도 ANSI 스타일이 아니라 K&R 스타일만 써야 하는 진짜 무지막지한 골동품이라고 한다. Windows 1.x는 파스칼로 개발되었다고 들었는데 그래도 그때부터 C 형태의 SDK는 있었던 모양이다.

Posted by 사무엘

2013/11/28 08:29 2013/11/28 08:29
, ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/903

Windows GUI 프로그램은 잘 알다시피 메시지로 운영체제와 의사소통을 하는 게 핵심이다. “이 창은 응답이 없음. 프로그램을 강제 종료할까요?”라고 판단을 하는 기준은 바로 n초 이상 GetMessage/PeekMessage 함수를 호출하지 않는 프로그램이다.

CreateWindowEx로 창을 하나 만든 뒤 메시지 loop은 GetMessage로 메시지를 받아서 그걸 DispatchMessage로 넘겨 주기를 반복하는 형태이다.
비록 메시지를 윈도우 프로시저로 전달하는 함수로는 CallWindowProc도 있겠지만, Dispatch는 타이머 메시지를 윈도우 프로시저 대신 lParam에 지정된 타이머 프로시저로 직통 전달하는 일까지 한다. 즉, 하는 일의 범위가 더 넓다. 그리고 Call은 메시지 큐를 처리하는 게 아니라 윈도우 프로시저의 서브클래싱용으로 쓰라고 있는 물건이다.

메시지를 Dispatch하기 전에 보통은 translation이라고 불리는 전처리 과정이 필요하다. TranslateMessage 함수가 그 일을 하는데, 키보드 WM_(SYS)KEYDOWN / WM_(SYS)KEYUP 메시지로부터 WM_(SYS)CHAR 메시지를 추가로 생성해 준다. 현재 설정되어 있는 키보드 드라이버의 정보를 토대로 가상 키코드를 해석하여, 그 키가 나타내는 입력 문자를 알려 준다는 뜻이다. 유럽 문자를 입력할 때 쓰이는 dead key를 처리하는 것도 translator의 몫이다.

이때 새로 생성된 메시지는 이 윈도우를 구동하는 스레드의 메시지 큐에 추가로 예약되어서 다음번 GetMessage 함수 호출 때 걸려 나온다. 인자로 전달된 MSG 구조체의 내용이 지금 당장 바뀌지는 않는다. 사실, 문자를 입력받는 윈도우가 아니라면 translation은 꼭 필요하지는 않은지도 모르겠다.

그런데 메시지를 굳이 윈도우 프로시저로 dispatch하기 전에, 응용 프로그램이나 다른 API 함수가 곧장 메시지를 가로채야 하는 경우는 굉장히 많이 있다. 액셀러레이터 단축키를 처리하는 TranslateAccelerator, 그리고 Ctrl+F6 같은 MDI 공용 단축키를 처리하는 TranslateMDISysAccel이 그 예이다.
TranslateMessage는 그런 관문들을 모두 통과한 메시지가 dispatch 직전에 최종적으로 거치는 관문일 뿐이다.

이런 절차가 한둘이 아니기 때문에 MFC의 CWnd 클래스는 그런 코드를 적절히 넣으라고 PreTranslateMessage라는 가상 함수까지 마련해 놓았다. 이 함수에서 키보드 메시지를 조작하여 엔터가 눌려도 대화상자가 종료되지 않게 하는 것 정도는 프로그래밍 초보 시절에 다들 해 보았을 것이다. 그러고 보니 이렇게 dispatch 전단계에서 조작하는 메시지는 다들 키보드 관련 메시지인 경우가 많다.

그리고 이런 식으로 전용 함수를 통해 미리 처리되는 또 다른 대표적인 메시지들은 바로.. 대화상자 관련 메시지들이다.
이걸 담당하는 물건으로는 IsDialogMessage라는 함수가 있다.

물론, MFC의 경우 저 함수를 포함해 위에서 언급한 각종 전처리, translation을 이미 알아서 전부 호출하며 메시지 loop과 심지어 WinMain 함수까지 몽땅 라이브러리 내부에다 짱박아 뒀기 때문에 MFC를 사용하는 프로그램이라면 자신이 직접 그런 함수를 또 호출해야 할 일은 거의 없을 것이다.
그러나 운영체제와 응용 프로그램 사이에 어떤 메커니즘으로 통신이 오가는지 알고는 있을 필요가 있다.

대화상자 안에서 사용자가 tab 키를 눌렀을 때 컨트롤들의 포커스가 바뀌는 것, Alt+알파벳을 눌렀을 때 특정 컨트롤로 바로 이동하는 것, 엔터를 눌렀을 때 '확인' 종료가 되고 ESC를 눌렀을 때 '취소' 종료가 되는 것 따위는 대화상자의 윈도우 프로시저의 관할이 아니다. 윈도우 프로시저가 메시지를 받기 전에 저 IsDialogMessage 함수가 일찌감치 처리한다. 심지어 default 버튼의 테두리를 굵게 칠하는 것조차도 저 함수가 담당한다.
물론 그런 전처리는 대화상자가 독단적으로 하는 게 아니라 자기 아래의 컨트롤에게 WM_GETDLGCODE 메시지를 보내서 컨트롤이 원하는 키보드 처리 양상에 대해서 물어는 보고서 한다.

DialogBox 함수로 modal 대화상자를 만들었다면야 그 함수가 자체적으로 메시지 loop을 돌면서 이런 처리를 모두 알아서 해 준다. 그러나 문제는 modeless 대화상자이다. modeless 대화상자는 그 창을 만든 응용 프로그램의 main 메시지 loop를 같이 쓰면서 돌아가기 때문에 그 loop에서 IsDialogMessage 함수를 호출하는 로직이 추가되어야 한다.

대화상자에서 엔터 키가 들어왔을 때의 동작에 대해서는 살짝 주의할 점이 있다.
일반 버튼은 자체적으로 엔터 키를 처리한다. 그래서 다른 모든 컨트롤들을 사용 중일 때 엔터를 누르면 '확인' 버튼이 눌러진 것으로 처리되고 대화상자가 곧장 종료되지만, '취소'나 '적용' 같은 다른 버튼에 키보드 포커스가 가 있을 때 엔터를 누르면 해당 버튼이 눌러진 것으로 처리된다.

즉, 엔터는 space와 사실상 동일하게 처리된다. 차이가 있다면 space는 key down 시점 때는 버튼이 눌러진 모습만 표시되고 key up 시점일 때 명령이 먹히는 반면, 엔터는 key down 때 곧바로 먹힌다는 것이 전부이다.
다만, 대화상자 안에 또 대화상자가 자식 윈도우로 생성되었고 자식 대화상자 안에 있는 버튼을 space가 아닌 엔터 키로 눌렀을 경우,

WM_COMMAND+BN_CLICKED 메시지는 자식 대화상자의 윈도우 프로시저로 전달되는 게 아니라 겉의 최상위 대화상자의 윈도우 프로시저로 전달된다.
그래서 그 버튼을 엔터 키로 누른 동작은 일반적으로 제대로 인식되지 않거나 최악의 경우 오동작--부모 대화상자와 자식 대화상자에 우연히 ID값이 같은 버튼이 공존한다면!--까지 하게 된다.

왜 그렇게 동작하는지 정확한 이유는 난 모르겠다.
물론, 일반적으로 엔터를 눌러서 대화상자를 닫는 메시지 자체는 자식 대화상자가 아니라 최상위 대화상자에다가 전달되는 게 개념상 올바르다.
하지만 그런 default 버튼이 아니라 일반 버튼을 엔터 키로 누르는 동작까지 왜 엉뚱한 곳으로 가는 걸까?

대화상자 안에 또 대화상자를 만드는 건 운영체제가 제공하는 프로퍼티 시트가 대표적인 예인데 그건 운영체제가 알아서 버튼의 처리를 잘 해 주는 듯하다. <날개셋> 타자연습 같은 프로그램에서 탭 안에 있는 버튼을 엔터로 눌러 보면 잘 안식된다.

그러나 자체적으로 자식 대화상자들을 표시하는 <날개셋> 한글 입력기의 제어판, 그리고 VMware, 반디집, EditPlus 등의 유수의 소프트웨어들이 제공하는 종합 설정 대화상자들을 살펴보면, 자식 대화상자 안의 버튼은 space만 인식되지 엔터 키로 인식되지 않는 걸 알 수 있다. (아래 그림에서 왼쪽)
단, Microsoft Visual Studio는 예외. '도구-옵션' 대화상자의 내부에 표시된 자식 대화상자들의 버튼은 엔터 키로 잘 인식된다. (아래 그림에서 오른쪽) 치명적인 버그 같은 부류는 아니지만 운영체제의 특성 때문에 발생하는 좀 이상한 면모라 하겠다.

사용자 삽입 이미지사용자 삽입 이미지
WM_COMMAND+BN_CLICKED 메시지는 lParam으로 이 메시지를 보낸 컨트롤의 윈도우 핸들을 친절하게 일일이 알려 준다.
그렇기 때문에 그런 버튼을 누르는 걸 인식하려면, 최상위 대화상자의 윈도우 프로시저에서 lParam을 검사하여 이것이 자식 대화상자가 아니라 내 대화상자의 버튼이 보낸 메시지가 맞는지를 확인해야 한다. 아니라면 그 버튼의 진짜 부모 윈도우--GetParent 함수로 확인--에다가 메시지를 도로 보내 버리면 된다.

Visual Studio의 옵션 대화상자도 Spy++로 동작을 확인해 보면, WM_COMMAND+BN_CLICKED 메시지가 두 번 가는 걸 보니 그런 식으로 동작하는 듯하다.

Posted by 사무엘

2013/11/22 08:36 2013/11/22 08:36
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/901

자고로 프로그래밍 언어는 구문이나 예약어 같은 원론적인 것만 정의하는 게 아니라, 그 문법을 토대로 프로그램의 작성에 필요한 각종 기본적인 자료구조와 알고리즘, 입출력 기능들도 라이브러리 형태로 제공한다. 후자의 디자인도 프로그래밍 언어의 정체성에서 차지하는 비중이 매우 크다.

예를 들어 printf, qsort, malloc, fopen 같은 함수를 사용했다면 그 함수들의 몸체도 당연히 프로그램 어딘가에 빌드되어 들어가야 한다. 아니, 애초에 main 함수나 WinMain 함수가 호출되고 각종 인자를 전해 주는 것조차도 그냥 되는 일이 아니다. 이런 것은 C/C++ 언어가 제공하는 런타임 라이브러리가 해 주는 일이며, 우리가 빌드하는 프로그램에 어떤 형태로든 코드가 링크되어 들어간다.

C/C++은 그나마 기계어 코드를 생성하는 언어이기 때문에 그런 런타임의 오버헤드가 작은 편이다. 그러나 비주얼 베이직(닷넷 이전의 클래식)이라든가 델파이는 RAD 툴이고 언어가 직접 GUI까지 다 커버하다 보니 언어가 제공하는 런타임 오버헤드가 크다.
자바나 C#으로 넘어가면 런타임이 단순 코드 오버헤드로 감당 가능한 정도가 아니라 아예 가상 기계 수준이다. 프로그램이 기계어 코드로 번역되지도 않으며, garbage collector까지 있다.

그렇게 프로그래머의 편의를 많이 봐 주는 언어들에 비해 '작은 언어'를 추구하는 C/C++은 도스나 16비트 윈도 시절에는 런타임 라이브러리가 static 링크되는 게 당연시되곤 했다. 오버헤드 자체가 수천~만 몇천 바이트밖에 되지 않을 정도로 매우 작은 편이고, 저수준 언어인 C/C++은 당연히 standalone 바이너리를 만들어야지 무슨 다른 고급 언어처럼 런타임 EXE/DLL에 의존하는 바이너리를 생성한다는 건 좀 안 어울려 보이는 게 사실이었다.

그래서 C/C++로 개발된 EXE 파일은 내부를 들여다보면 대체로, 링크되어 들어간 런타임 라이브러리의 이름과 개발사를 나타내는 문자열이 들어있었다. 볼랜드나 마이크로소프트 따위. 그래서 이 프로그램이 어느 컴파일러로 만들어졌는지를 얼추 짐작도 할 수 있었다.

C 런타임 라이브러리도 static이 아닌 DLL 형태로 제공하려는 발상은 Windows의 경우 아무래도 32비트 NT의 개발과 함께 시작된 듯하다. 그래서 윈도 NT 3.1의 바이너리를 차용해서 개발되었다는 과거의 Win32s를 보면 crtdll.dll이라는 파일이 있는데 이것이 운영체제가 기본 제공하는 프로그램들이 공용하는 C 런타임 DLL인 듯하다. 즉, 메모장, 문서 작성기, 그림판 등의 프로그램들이 호출하는 sprintf 같은 C 함수들의 구현체가 거기에 담겨 있다는 뜻이다.

재미있게도 윈도 NT의 경우, kernel32보다도 먼저 로딩되는 ntdll.dll이 내부적으로 또 각종 C 함수들의 구현체를 제공한다. 커널이 제대로 로딩되기도 전에 실행되는 프로그램이 공유하는 C 함수들이라고 한다.

과거의 윈도 9x의 프로그램들은 비록 32비트이지만 운영체제가 자체적으로 공유하는 C 런타임 DLL은 없다.
다만, 윈도 NT 3.x 이후로 비주얼 C++이 32비트 개발툴로 자리매김하면서 이 개발툴의 버전에 따라 msvcrt20.dll, msvcrt40.dll이 제공되기 시작했고 이들은 윈도 9x에서도 기본 내장되었다. 비록 같은 C 런타임이지만 버전별로 미묘한 차이가 있는 모양이다.

그러다가 1996년에 출시된 비주얼 C++ 4.2부터 C 런타임 DLL은 더 변경을 안 하려는지 파일 이름에서 버전 숫자가 빠지고, 그 이름도 유명한 msvcrt.dll이라는 이름이 정착되어 버전 6까지 쭉 이어졌다.
이 이름은 비주얼 C++ 4.2 ~ 6이 생성한 바이너리가 사용하는 C 런타임인 동시에, NT 계열에서는 기존의 crtdll을 대신하여 운영체제의 기본 제공 프로그램들이 공유하는 C 런타임의 명칭으로도 정착했다.

그리고 9x 계열도 윈도 98부터는 mfc42.dll과 더불어 msvcrt.dll을 기본 제공하기 시작했다.
NT와는 달리 운영체제가 msvcrt.dll을 직접 쓰지는 않지만, 비주얼 C++로 개발된 프로그램들을 바로 실행 가능하게 하기 위해서 편의상 제공한 것이다. 과거의 유물인 msvcrt40.dll은 msvcrt.dll로 곧바로 redirection된다.
그 무렵부터는 오피스, IE 같은 다른 MS 사의 프로그램들도 C 런타임을 msvcrt로 동적 링크하는 것이 관행으로 슬슬 정착해 나갔다.

그렇게 윈도, VC, 오피스가 똑같이 msvcrt를 사용하는 구도가 한동안 이어졌는데..
21세기에 비주얼 C++이 닷넷으로 넘어가면서 그 균형은 다시 깨졌다.
C 런타임 라이브러리도 한 번만 만들고 끝이 아니라 계속 버전업이 되어야 한 관계로 msvcr70, msvcr71 같은 DLL이 계속해서 만들어진 것이다. 결국, 비주얼 C++ 최신 버전으로 개발한 프로그램은 C 라이브러리를 동적 링크할 경우, DLL 파일을 배포해야 하는 문제를 새로 떠안게 되었다.

이것이 비주얼 C++ 2005/2008에서는 더욱 복잡해졌다. C 라이브러리를 side-by-side assembly 방식으로 배포하는 것만 허용했기 때문이다. 쉽게 말해, 레거시 공용 컨트롤과 윈도 XP의 비주얼 스타일이 적용된 공용 컨트롤(comctl32.dll)을 구분할 때 쓰이는 그 기술을 채택했다는 뜻이다.

그래서 msvcr80/msvcr90.dll은 윈도 시스템 디렉터리에만 달랑 넣는다고 프로그램이 실행되지 않는다. 이들 DLL은 DLLMain 함수에서 자신이 로딩된 방식을 체크하여 이상한 점이 있으면 고의로 false를 되돌린다. 그렇기 때문에 이들은 반드시 Visual C++ 재배포 런타임 패키지를 통해 정식으로 설치되어야 한다.

런타임 DLL간의 버전 충돌을 막기 위한 조치라고 하나 이것은 한편으로 너무 불편하고 번거로운 조치였다. C 라이브러리가 좀 업데이트돼 봤자 메이저도 아니고 마이너 버전끼리 뭐가 그렇게 버전 충돌이 있을 거라고..;; 나중에는 여러 프로그램들을 설치하다 보면 같은 비주얼 C++ 2005나 2008끼리도 빌드 넘버가 다른 놈들의 재배포 패키지가 설치된 게 막 난립하는 걸 볼 수 있을 정도였다. 가관이 따로 없다. 당장 내 컴에 있는 것만 해도 2008 기준으로 9.0.32729까지는 똑같은데 마지막 숫자가 4148, 6161, 17, 4974... 무려 네 개나 있다.

개발자들로부터도 불편하다고 원성이 빗발쳤다. MS Office나 Visual Studio급으로 수십 개의 모듈로 개발된 초대형 소프트웨어를 개발하는 게 아니라면, 꼬우면 그냥 C 라이브러리를 static 링크해서 쓰라는 소리다.
그래서 비주얼 C++ 2010부터는 C 라이브러리 DLL은 다시 윈도 시스템 디렉터리에다가만 달랑 집어넣는 형태로 되돌아갔다. 다시 옛날의 msvcrt20, msvrt40, msvcr71처럼 됐다는 뜻이다.

윈도 비스타 타임라인부터는 운영체제, VC, 오피스 사이의 관계가 뭔가 규칙성이 있게 바뀌었다.
오피스는 언제나 최신 비주얼 C++ 컴파일러가 제공하는 C 라이브러리 DLL을 사용하며, 운영체제가 사용하는 msvcrt도 이름만 그럴 뿐 사실상 직전의 최신 비주얼 C++가 사용하던 C 라이브러리 DLL과 거의 같다.

그래서 오피스 2007은 msvcr80을 사용하며, 오피스 2010은 비주얼 C++ 2008에 맞춰진 msvcr90을 사용한다. C 런타임 DLL도 꾸준히 버전업되고 바뀌는 물건이라는 것을 드디어 의식한 것이다. 비스타 이전에 윈도 2000/XP의 EXE/DLL들은 헤더에 기록된 링커 버전을 보면, 서로 사용하는 컴파일러가 다르기라도 했는지 통상적인 비주얼 C++이 생성하는 EXE/DLL에 기록되는 버전과 일치하지 않았었다. 9x는 더 말할 필요도 없고.

그럼에도 불구하고 msvcrt는 운영체제 내부 내지 디바이스 드라이버만이 사용하고, 비주얼 C++로 개발된 여타 응용 프로그램들은 언제나 msvcr##을 사용하게 용도가 확실하게 이원화되었다.
그래서 심지어는 똑같이 MS에서 개발한 한글 IME임에도 불구하고 Windows\IME 디렉터리에 있는 운영체제 보급용은 msvcrt를 사용하고, 한글 MS Office가 공급하는 IME는 Program Files에 있고 msvcr##을 사용한다. 둘은 거의 똑같은 프로그램인데도 말이다.

이것이 Windows와 C 런타임 라이브러리 DLL에 얽힌 복잡한 역사이다. 여담이지만 C 라이브러리 중에서 VC++ 2003이 제공한 msvcr71은 Windows 95를 지원한 마지막 버전이다. 2005가 제공한 msvcr80부터는 일부 보안 관련 코드에서 IsDebuggerPresent라는 API 함수를 곧장 사용함으로써 Windows 95에 대한 지원을 중단하였으며, 최하 98은 돼야 동작한다. VC++ 2008부터는 9x 계열에 대한 지원 자체가 중단됐고 말이다.

자, 여기서 질문이 생긴다. 그럼 C++은 사정이 어떠할까?

C보다 생산성이 훨씬 더 뛰어난 C++로 주류 프로그래밍 언어가 바뀌면서 표준 C++ 라이브러리에 대한 동적 링크의 필요성도 응당 제기되었다. 그러나 이것은 C 라이브러리보다는 시기적으로 훨씬 더 늦게 진행되었기 때문에 가장 먼저 등장하는 비주얼 C++의 DLL 이름이 msvcp50과 msvcp60이다. 즉, 비주얼 C++ 5.0 이전에는 선택의 여지 없이 static 링크만 있었다는 뜻이다.

더구나 이것은 전적으로 비주얼 C++ 소속이지, 운영체제가 따로 C++ 라이브러리 DLL을 제공하지는 않는다. MS에서 만들어진 제품들 중에 msvcp##를 사용하는 물건은 비주얼 C++ IDE와 컴파일러 그 자신밖에 없다.

C++ 라이브러리는 대부분 템플릿 형태이기 때문에 알고리즘 뼈대는 내 바이너리에 static 링크되는 게 사실이다. 그러나 그렇게 덧붙여지는 라이브러리 코드가 별도로 호출하는 함수 중에 DLL에 의존도를 지니는 게 있다. cout 객체 하나만 사용해도, 그리고 STL 컨테이너 하나만 사용한 뒤 빌드해 봐도 형체를 알 수 없는 이상한 메모리 관리 쪽 함수에 대한 의존도가 생긴다.

그래도 C 라이브러리 DLL은 사용한 함수에 따라서 printf, qsort 등 링크되는 심벌이 명확한 반면
C++ 라이브러리는 내부 구조는 이거 뭐 전적으로 컴파일러가 정하기 나름이고 외부에서 이들 심벌을 불러다 쓰기란 사실상 불가능하다는 큰 차이가 있다.

<날개셋> 한글 입력기는 C++ 라이브러리를 사용하지 않으며, 빌드 후에 생성된 바이너리를 인위로 수정하여 msvcr## 대신 강제로 운영체제의 msvcrt를 사용해서 동작하게 만들어져 있다.

Posted by 사무엘

2013/11/19 08:29 2013/11/19 08:29
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/900

※ 기독교가 세상적으로는 도저히 성공할 수 없고, 인간의 머리로 만들어 낼 수 없는 종교(?)인 이유

1. 여타 종교들을 한 치의 타협도 없이 단호히 배척하여 '따'를 자처한다.

2. '원수를 사랑하라' 등, 육신적인 가식· 위선으로는 도저히 흉내조차 낼 수 없는 요구를 한다.

3. '부활' 같은 도저히 믿어지지 않는 황당한 걸 가르친다. 사실 교주가 부활해서 무덤이 비어 있다고 가르치는 종교도 여기 말고는 없고..;;

4. 잘 믿으면 부귀영화 성공은커녕, 박해를 받을 거라고 대놓고 버젓이 예고한다.


이건 내가 정리한 건 아니고 L.E.맥스웰의 <우리는 십자가에 못 박힌 채 태어났다> 책에 있는 내용이다.

세상엔 복음에 반감을 갖고 있는 똑똑하고 '이성· 합리적인' 무신론자들이 엄청 많다. 인간이 만들어 낸 종교들의 각종 폐단들을 지적하면서 자신들은 반종교가 아니라 비종교를 표방한다고 그러는데...
그에 대한 나의 생각/반론은 이러하다.

1. 글쎄, 리처드 도킨스가 나처럼 있지도 않은 신을 무작정 쫓아다니는 불쌍한 무지렁이들을 너무 사랑한 나머지, 무신론을 설파하기 위해 나 대신 죽어 주기까지 했으면(그리고 부활까지 했으면).. 그 사람 주장도 좀 고려해 보겠다.

2. 내가 왜 태어났고 인생의 목적이 무엇이고 죽어서는 어떻게 되고, 절대적인 선과 악이 무엇인지.. 이런 것에 대한 관념이 없는 사람치고 건전하게 잘 살고 있는 사람은 난 못 봤다. 절대자 없이 인간이 과연 그렇게 자기끼리 질서정연하게 잘 살고 있었을까? 글쎄? 난 그렇게 보이지 않는데. ㅎㅎ

3. 위에도 잘 설명돼 있지만, 인간이 자기 머리로 종교를 만들었다면 나 같으면 단언하건대 철도교를 만들었지 기독교 같은 건 미쳤다고 만들겠나. 절대로 안 한다.

Looking for you 같은 마약 같은 황홀경 음악이 있고, 수인선 복선 전철과 동해남부선 광역전철의 부활 신앙이 있고, 국토 사랑 정신과 희락과 화평과 사랑이 넘치는 철도교를 믿으면 되지 뭐 하러 쓸데없이 사탄 마귀, 지옥, 심판, 휴거 같은 걸 논하겠나? 왜 골치아프게 영적 전투를 치러야 하나? 나도 종교에 대해서 도킨스만치는 그래도 생각을 해 보고 예수 믿는다. ㅎㅎ

이성· 합리적인 무신론자라면 이에 대한 진지한 고찰이 필요하다. 세상에 인간들이 당신보다 똑똑하지 못해서, 머리 쓸 줄 몰라서 기독교가 안 없어지고 있는 게 아니다.

※ 크리스천이 겪는 슬픔과 고통

크리스천이 아무리 죽음에 대한 준비가 다 된 사람이라 해도, 이와 별개로 죽는 과정은 충분히 두려울 수 있다. 그리고 고통 때문에 울부짖을 수 있다. 예수쟁이도 총 맞으면 죽는 보통 사람이며, 고문 당하면 괴로운 건 마찬가지다.
또한 크리스천이 아무리 부활의 소망이 있고 하늘나라에서 다시 만날 걸 기약한다 해도, 사랑하는 사람이 당장 죽었는데 당연히 슬퍼서 울 수 있다. 성경에도 그 유명한 Jesus wept가 있다.

그러나 크리스천은 뭔가 천추의 한이 맺히고 서러워서, 혹은 증오심과 원망이 맺혀서 “이놈/이것만 아니었으면 내가 요 모양 요 꼴 되지는 않았을 텐데” 같은 식으로 울 일은... 영적으로 잘 성장했다면 없는 게 정상일 것이다.

물론, 크리스천 중에 여전히 그런 것 때문에 세상 비관하고 앓는 소리 하는 사람이 있더라도 무작정 남을 판단하고 정죄하지는 말아야 할 것이다.
기독교 신앙이 모 아니면 도 식인 것은 진리이나, 그렇다고 해서 “이러지 못할 거면 걍 때려치워라” 같은 돌직구는 정말 신중하게 날려야 한다. 그런 걸로 기껏 자라려던 남의 믿음을 완전히 무너뜨리고 실족하게 해서는 안 된다.

Posted by 사무엘

2013/11/16 08:30 2013/11/16 08:30
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/899

내 주변의 크리스천 지인 중에는 크리스천의 ‘인격, 행실’에 대해서 정말 많은 관심을 갖고 거기에 심각하게 고민하는 분이 있다. 왜 있잖은가, “크리스천이 되기에 앞서 인간부터 돼야지!” 같은 식의 주장 말이다.

크리스천으로의 사명감과 책임감이 얼마나 투철했으면, 세상이 복음을 받아들이지 않는 이유에 대한 해석도 다르다. 세상이 악하고 마음이 강퍅해져서가 아니라, 기존 교회들이 병신같이 선교 행위를 하고 예수 간증을 잃었기 때문이라는 점을 아주 강조한다. 성경의 표현을 빌리자면, 고후 4:4보다 롬 2:23-24를 선호한다는 뜻.

이런 성향이 종교적으로 극단으로 치달으면, 결국 선행이 드러나 있지 않은 사람은 구원받은 것도 아니라는 식으로 예정론을 잘못 적용한 주권 구원 내지 행위 구원 쪽으로 빠진다.

그리고 이런 성향이 정치적으로 극단으로 치달으면, 오로지 대형 교회들을 흠집 내고 잡아먹기 위해서 불신자들하고까지 손잡을 지경인 진보 성향으로 바뀐다.

뭐, 저 정도의 잘못된 극단으로 빠진 게 아니라면, 그런 성향에도 일리가 있는 지적이 분명 있다. 예전에 같은 교인들로부터 몰상식적이고 무례하고 육신적인 언행 때문에 상처를 많이 입었거나, 아니면 기성 교회의 비성경적인 관행에 트라우마가 생긴 경험 때문에 그런 성향이 깊어진 게 아닐까 싶다. 이해는 한다.

그런데 이 이슈에 대한 나의 내면의 생각을 좀 말해 볼까?

첫째, 기독교의 교리가 “크리스천이 되기에 앞서 인간부터 돼야지!”였다면, 나는 크리스천이 절대로 못 됐으며 인간은 더욱 못 됐을 것 같다. 나 자신부터 옛날에는 인간성· 사회성, 인격 따위가 지금보다 훨씬 더 거칠고 더러웠다. 그나마 예수 믿고 나서 같은 성도들끼리 부대끼면서 아주 차츰차츰 개선된 것이다.

둘째, 난 기독교의 탈을 쓴 종북이 존재한다는 사실 하나만으로도 ‘교인’들의 행실에 대한 기대 따위는 진작에 안드로메다에다 보내고 왔다. 이건 무슨 대형 교회의 부정부패나 몰상식한 선교 행위 같은 것하고는 아예 레벨이 다르고 차원이 다른 악행이지 않은가! (걔네들은 애초에 예수님을 내 구주로 제대로 영접도 안 한 사람일 거라고 개인적으로 생각은 한다)

종북이 예수 믿고 구원받으면 그 구원에 감격하고 지금 처한 여건을 주신 하나님께 감사하고, 국가와 민족에 자부심과 애착이 생기고, 우리에게 있는 자유가 얼마나 소중한지와 지금 진짜 인권 유린을 당하고 있는 곳이 어딘지를 다 자동으로 깨달을 줄 알았는데, 종북이 예수 믿으면 그냥 구원받은 종북이더라!

이게 겨우 일개 인격이나 성품 따위하고 비교가 가능한 문제일까? 성경 말씀이 그런 사람들의 사상 하나조차 제대로 바로 이끌어 주지 못한 걸까?

그러니 난 애초에 혼의 구원과 영원이 걸린 종교 문제는 전적으로 핵심 사상인 교리의 우월성을 보고 선택했지, 주변 사람들의 말단 행실이나 평판 같은 건 “개별적인 case by case”일 뿐, 진지한 고려 대상으로 여기지 않았다.

정말로 비성경적인 수위가 도를 넘어서는 잘못된 목사나 잘못된 교회가 있으면, 당신 혼자 그 교회를 조용히 탈퇴하면 된다. 대한민국은 자유가 있는 좋은 나라이다. 당신이 그런다고 해서 당신을 고문하거나 수용소로 보낼 사람은 아무도 없다.

그리고 도저히 구원받았을 것 같지 않은 막장 성도라면.. 성경에 규정된 대로 징계하고 쫓아내든가, 아니면 그냥 교제 끊고 이교도나 세리 대하듯이 최소한의 예의와 격식만 차려서 대하면 된다. 그 사람이 만에 하나 진짜 구원받은 게 맞다면 나중에 하늘나라에서나 오해가 풀리기를 바라는 수밖에.

영적 전쟁터는 원래 그 어떤 희한한 짓 험한 꼴이 벌어진다 해도 이상할 게 없는 바닥 아닌가?
크리스천이 행동이 병신이었던 게 어디 한두 번이었으며, 그게 그렇게까지 납득이 안 되는 일일까? 난 그렇게 생각하지 않는다.

그런 현실을 지나치게 탓하고 비관하는 건, 예수님이고 성경이고 복음이고, 게다가 그냥 성경도 아니고 신줏단지 같이 떠받드는 KJV 성경조차도 현실에서는 아무짝에도 쓸모가 없다고, 크리스천이라는 사람이 자기 입으로 영적 전투의 패배를 스스로 인정하는 꼴이나 다름없다.

그냥 구원받는 것하고 예수님의 제자의 삶을 사는 건 별개의 문제이다. 예수 믿는 사람이라고 해서 다 자기와 같은 사상을 지니고 자기처럼 성장하고 자기처럼 행동할 거라고는 절대로 기대하지 말지어다.

교회는 영적 전투 수행을 위한 무슨 소수정예 특수부대가 아니다. 이 세상에 아무 결점이 없는 완벽한 성도들로만 이뤄진 교회가 존재한다면, 당신이 그 교회에 가입하는 순간부터 무결성이 깨진다는 심정으로 교회 생활을 하면 된다.

구원과 행실 사이의 관계 문제는 하나도 어려울 것 없다.
보이지 않는 믿음을 보이는 행위로 나타내야 한다는 내 안의 성령님의 압박이 느껴진다면, 남 신경 쓰지 말고 당신이나 잘하면서 남에게 좋은 본을 보이면 된다.

잘못하고 있는 교회 지체를 성경으로 일깨우면서 권면하는 것 이상으로,
누구 다른 사람 때문에 복음이 실추되고 있다는 식으로 피해의식은 어떤 경우에도 가질 필요 없다.

Posted by 사무엘

2013/11/08 08:17 2013/11/08 08:17
,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/896

<날개셋> 한글 입력기 7.11

<날개셋> 한글 입력기 7.1은 다음 7.3이나 7.4가 나올 때까지 오랫동안 안정적으로 쓰일 수 있을 것 같았으나.. 시간이 흐르고 보니 부득이 소규모 7.11 업그레이드가 3주 남짓한 시간 만에 나오게 됐다.

이 버전에서는 외부 모듈이 다음과 같이 대대적으로 개선됐다.

1.
TSF B급 프로그램(메모장 같은)에서 '호환용 한글 자모'를 쓰고도 옛한글이 전혀 입력되지 않던 문제를 해결했다.
이것은 직전 버전인 7.1에만 있던 버그이다. TSF A급 프로그램에서 두벌식 도깨비불 현상에 의해 옛한글이 곧장 시작되었을 때 조합이 끊어지던 문제를 해결했었는데 불행히도 그게 TSF B급 프로그램에서는 심각한 오동작을 유발하고 있었다.
결국 A급일 때와 B급일 때를 인위적으로 나누어 따로 동작하게 하는 방식으로 두 토끼를 모두 잡았다.

한글 IME 개발이라는 게 이렇게 지저분하고 어렵다.
모호한 스펙 때문에 IME를 사용하는 구현체별로 문서화되지 않은 예측 불가능한 동작이 너무 많으며, 이것을 하나하나 다 맞춰 줘야 한다. 한 프로그램에다 동작을 맞춰 주면 다른 프로그램에서 오동작하는 게 왕왕 있다.

물론, TSF B급 프로그램에서는 '호환용 한글 자모'를 써서 첫 조합은 한 글자 길이를 보장시킨 뒤에 제한적으로 옛한글 입력이 가능하지만, 두벌식의 경우 도깨비불 현상으로 옛한글이 곧장 시작되었을 때 조합이 끊어지는 건 어쩔 수 없다.
이런 문제 때문에 MS에서는 논란의 여지를 없애기 위해 자기가 개발한 옛한글 입력기는 오로지 TSF A급 프로그램에서만 동작하게 제약을 걸었다. 지원하는 글자판 자체도 두벌식밖에 없기도 하니 말이다.

2.
Windows 8에는 일명 메트로라고 불리기도 한 Modern UI가 있고 거기서 일부 앱은 권한이 극도로 제한된 상태로 동작한다. 본인은 입력기를 테스트할 때 날씨(Weather) 앱을 실행한 뒤 장소 추가 대화상자를 꺼내 보곤 했다. 그런데 테스트를 하려면 인터넷 연결을 꼭 해야 해서 개인적으로 무척 성가시고 불편함을 느꼈다.

어쨌든, 그런 제한 모드에서는 IME가 자기 입력 설정을 불러올 수조차 없어서 어쩔 수 없이 설치 직후의 기본 입력 설정으로 동작한다. 이때는 입력 설정이 제대로 로딩되어 있는 다른 프로그램--데스크톱 앱 또는 권한 제약이 없는 Modern 앱--을 미리 실행해 놓고, 제약이 걸린 앱도 덩달아 같이 실행해야 입력 설정이 동기화된다. 이것은 기술적으로 더 어쩔 수 없는 귀결이다.

그런데 이번 버전에서는, 제약이 걸린 앱을 먼저 실행하고 제약이 없는 앱(데스크톱 앱 포함)을 “나중에” 뒤늦게 실행한 뒤, 제약이 걸린 앱으로 되돌아오더라도 입력 설정이 동기화되도록 프로그램을 개선했다. Modern 앱에서 <날개셋> 한글 입력기의 사용 편의성이 더 향상될 것으로 기대한다.
당연히.. 제약이 없는 앱을 실행한 뒤엔 그 프로그램에서 <날개셋> 한글 입력기 외부 모듈을 로딩도 하고서 돌아와야 한다.

3.
그리고 드디어, 드디어...
외부 모듈도 현대 한글뿐만 아니라 옛한글까지 bksp 낱자 단위로 지우기 및 달라붙기 같은 기능이 동작 가능해졌다. 물론 TSF A급 프로그램 한정이고, 단순한 한글 자모 나열이 아니라 filler까지 정규화가 잘 된 글자에만 한해서 말이다.

이 기능을 구현하는 기반은 사실 지난 6.5 버전 때 이미 다져져 있었다. 그러나 실제로 제공되지는 못하고 봉인되어 있었는데,
그건 TSF A급 프로그램에서 존재하던 옛한글 조합 관련 버그 때문이었다.
그래서 그 버그를 고치면서 봉인돼 있던 기능까지 다시 살펴보게 되었고, 결국 이것도 덩달아 구현에 성공한 것이다. 만세! 한글 처리 기술의 진보를 이뤘다.

외부 모듈과 관련된 위의 세 이슈가 중요한 것이고 다음은 사소한 변화 사항들이다.

(1) 이 프로그램은 입력 설정이 없는 경우 MS 한글 IME의 설정이 어떻냐에 따라서 세벌식이나 두벌식을 자동으로 가져온다. 그런데 0번 말고 2번에 배당되는 기본 한글 글자판은 언제나 세벌식 옛한글로 고정이었다.
이제부터는 0번이 두벌식으로 맞춰지면 2번의 옛한글 글자판도 두벌식 옛한글로 지정되게 바뀌었다.

(2) 영문 about 대화상자에 layerd 오타-_-를 잡았다. 2004년에 나온 3.0의 영문 GUI 때부터 지금까지 줄곧 존재했던 오타이다. -_-;;; 오타가 그 단어의 실제 발음과 직관적으로 잘 대응하는 편인 관계로, 오타가 있는 줄 9년이 넘게 꿈에도 모르고 있었다.
그리고 편집기의 편집 화면 옵션 대화상자에 있던 '이동줄'이라는 단어도 '스크롤 막대'라고 MS 표준 번역 용어로 바꿨다. 이 역시 해당 옵션이 처음으로 추가되었던 3.0 버전 때부터 썼던 단어인데 드디어 변경.. ㅎㅎ
사실 '이동줄'은 한글 윈도 3.1의 도움말에 있던 용어이다.

(3) 지난 7.1에서는 앞으로 '고급 입력 스키마'를 재개발할 것을 염두에 두고 기존 '동시 입력 스키마'를 제거했다.
그랬는데, 이 입력 스키마를 사용하고 있는 분으로부터 요청을 받고 그걸 다시 원상복귀시켰다.
다만 이제 이 입력 스키마는 이름 뒤에 '임시용'이라는 단서가 붙었으며 영문 명칭에는 아예 legacy라는 단어가 추가되었다.

(4) 화면 키보드 입력 도구가 지금까지 크기가 너무 작은 게 흠이었는데, 작게-중간-크게 3단계로 크기를 조절하는 기능을 추가했다.
물론 글쇠 자체는 여전히 16*16 고정된 크기로만 찍히지만, '중간'으로만 해도 고해상도 화면에서는 글쇠배열이 훨씬 더 시원스럽게 보일 것이다.

(5) 두벌식 종성으로 입력한 종성으로 중성+종성을 한꺼번에 입력하여 도깨비불 현상을 일으킬 때, 내부 처리가 좀 더 정확하게 되도록 입력 엔진을 개선했다. 내부 사연이 좀 복잡하므로 이에 대한 자세한 내역은 별도의 글로 다루도록 하겠다..

(6) <날개셋> 편집기의 찾기 기능을 다소 손질하여, 찾는 문자열 영역이 한글을 이루는 글자의 중간에 걸치는 것은 정상적인 찾기 결과로 인정하지 않게 했다. 그래서 'ㅎㆍ'를 검색하면 정말로 'ㅎㆍ'만 걸리지, 'ㅎㆍㄴ'이 걸리지는 않게 했다. 'ㅎㆍ'로 'ㅎㆍㄴ'을 찾는 건 '한글 낱자 단위로' 옵션을 켰을 때에만 가능하다.

업데이트가 귀찮으시더라도, 부디 최신 버전을 사용하여 프로그램의 원 저자가 의도한 모든 기능을 마음껏 활용하시기 바란다.
아울러, 10월 한 달간 두 분이 후원금을 보내 주셔서 누적 후원자 수는 세 분이 되었다. 태어나서 이런 걸 연달아 받아 보는 경험이 거의 처음이어서 감개무량하고 보람을 느낀다. 감사드리는 바이다.

Posted by 사무엘

2013/11/04 19:23 2013/11/04 19:23
Response
No Trackback , 14 Comments
RSS :
http://moogi.new21.org/tc/rss/response/895

(上에서 이어짐)

사용자 삽입 이미지

“한두 명이 그렇게 일본인 몇 명하고 목숨을 맞바꾸는 식으로 백 날 노력해 봐라. 독립이 되나? 조선의 대외 이미지만 나빠지지 계란으로 바위 치기일 뿐이다.” 이렇게 무력 독립 투쟁을 평가절하하는 편인 사람들이 과거에나 지금에나 있다. 외교파이던 이 승만도 딱 저런 견해를 지녔던 사람이고... 비록 그 생각 역시 일리가 있긴 하지만, 실제로 폭탄을 들고 무장 투쟁을 했던 독립 운동가들도.. 그런 것 정도는 다 예상하고 감안했던 사람이다. 그러고도 자기 목숨을 바쳤던 것이다.

사용자 삽입 이미지

이거.. 진짜 윤 봉길이 맞는지 논란이 일기도 했던 사진이다.
실제로 윤 의사는 체포 직후부터 일본 헌병들에게 무자비하게 구타당해서 피떡이 된 상태였지만, 일본은 대외적으로 신사다움(?)을 강조하기 위해 다른 멀쩡한 사람을 정중히 끌고 가는 사진을 대외적으로 내보냈다고 그러는데..
하지만 윤 의사의 후손 중 어떤 분은 저게 윤 의사가 맞다고 증언하기도 했다고 한다.
다만, 위의 사람하고 아래의 사람은 아무래도 얼굴색을 포함해 인상이 좀 달라 보인다. 정말 동일 인물 맞나?

사용자 삽입 이미지

사용자 삽입 이미지
밖으로 나가면 윤 봉길 의사 동상이 있다. 날씨가 온통 흐리고 비가 오기 직전이어서 색감이 저렇게 됐다.
그런데 동상의 얼굴은 사진으로 보는 윤 의사와는 인상이 좀 다르게 느껴진다.
이것으로 기념관 관람 후기는 마치고, 숲 남부의 기념비/위령비 인증샷을 남기겠다.

4. 양재 시민의 숲 남부에 있는 3대 비석

가장 먼저 나오는 것은 유격 백마 부대 충혼탑이다.

사용자 삽입 이미지

우리나라가 왜 10월 1일을 국군의 날이라고 기념하는지 아시는가? 이 날이 바로 우리 국군이 6· 25 때 38선을 넘어 이북 땅으로 최초로 진군한 날이기 때문이다.

1950년 6· 25 전쟁이 터진 직후, 잘 알다시피 우리나라는 겨우 사흘 만에 서울을 빼앗겼고, 대통령이 부산까지 피난을 가야 할 정도로 나라가 없어질 위기에 몰렸었다.
그러나 UN군이 참전하고 인천 상륙 작전이 성공하면서 전세는 역전되었고, 9월 28일에 서울을 수복· 탈환하는 데 성공했다. 빼앗긴 지 딱 3개월 만이다! 그리고 10월 1일엔 38선을 넘었으며, 그 달 19일엔 평양을 점령했다.
11월쯤에는 국군이 압록강과 두만강 물을 떠다가 대통령에게 진상할 수 있을 정도가 됐다. 김 일성 패당 무리들을 완전히 추방하고 대한민국 자유 통일이 눈앞에 있었는데..

하지만, 하지만...
그 당시 중국도 아닌 중공군이 북한의 원군으로 참전하면서 국군과 UN군은 평안도 일대에서 후퇴할 수밖에 없었다.
이런 상황에서 평안북도 일대에서 몇몇 학생과 젊은이들이 정식 군번도 없이... 옛날 식으로 말하자면 '의병'을 조직하여 북한군과 교전을 벌였다. 2600여 명의 병사들 중 500여 명(552명이라 함)이 전사했으나, 이들은 정말 큰 공을 세웠다고 한다. 그들의 전적이 없었다면 1· 4 후퇴도 타이밍이 더욱 앞당겨져서 12· xx나 11· xx 후퇴가 됐을지도 모른다.

이 기념비는 바로 그들의 공적을 기리는 기념비다. 현장에 게시된 설명문은 이렇게 끝난다.
“길 가는 손들아! 잠시 걸음을 멈추고 스무 살 안팎 젊은 목숨을 반공 구국에 기꺼이 바친 뜻을 새기고 넋을 기려 다오.”

사용자 삽입 이미지

그 다음으로 가장 큼직한 이 비석은 1987년 11월 29일, 대한 항공 858편 폭파 사건 희생자의 위령비이다. 1988년 서울 올림픽을 보이콧한 정도가 아니라 방해까지 하려는 목적으로 북한이 보낸 공작원이 이라크 발 대한민국 행 대한 항공 소속 여객기에다 폭탄을 슬쩍 설치한 것이다.
이것이 터지면서 그 비행기는 인도양 상공 망망대해 위에서 실종되었으며, 승객 95명, 승무원 20명 총 115명이 전원 사망했다. 그리고 사망한 정도를 넘어 시신조차 한 구도 못 건졌다.

일본인으로 위장했던 북한의 공작원 커플은 외국에서 체포되었다. 남자는 검거 직후, 사전에 훈련받았던 대로 청산가리 앰플--윤 봉길 의사에게도 자결용으로 차라리 이런 간편한 물건이 있었으면 더 좋았겠다만--을 깨물어서 자살했으나 여자는 실패하여 국내로 송환됐다. 그녀의 이름은 김 현희. 맨날 인권 유린이라고 비난받아 온 코렁탕은 바로 이런 인간들을 조지라고 있는 필요악일 게다. 그러나 그녀는 전향 후 사면받고 우리나라에서 지금까지 잘 살아 있다.

참고로 북한은 1986년 서울 아시안 게임 직전에도 남의 나라 잔치에 찬물을 끼얹기 위해 김포 공항 청사 안에서 폭탄 테러를 벌인 적이 있었다. 북괴 천하의 개쌍놈들의 만행을 잊지 말아야겠다.
그리고 이런 놈들에 대한 트라우마 때문에, 항공업계에서는 누가 비행기에 탔다가 여행을 포기하고 도로 내린 경우, 기내를 싹 다 수색하고 수하물 검사를 처음부터 다시 하는 번거로운 절차가 추가된 것이다.

사용자 삽입 이미지

끝으로, 가장 남쪽에 가장 최근에 생긴 이 비석은.. 북한과는 관계가 없긴 하다만 그저 한숨뿐. 6· 25 이래로 평시에 단일 사고로 가장 큰 인명 피해를 낸 삼풍 백화점 붕괴 사고 희생자의 위령비이다. 공식 확인된 사망자 수는 502명. 아까 500여 명의 저 백마 부대 유격 대원들은 그래도 전투 중에 영예롭게 전사하기라도 했지, 마른 하늘에 날벼락을 맞은 저 희생자들은 대체 뭐냐. (하긴, 대한 항공 858편 희생자도 마찬가지겠지만)

여기 주변엔 유족들이 헌화해 놓은 꽃을 가져가지 말라는 경고문이 붙어 있더라.
유족들의 희망 사항은 삼풍 백화점이 있던 자리에 이런 위령비가 세워지는 것이었으나, 그렇게 되지는 못했다. 거기는 워낙 금싸라기 땅인지라 아크로비스타라는 다른 주상 복합 주택이 들어선 지 오래다.
참고로 성수대교 붕괴 사고 희생자 위령비는 현장과 비교적 가까운 성수대교 북단의 한강 둔치에 들어서 있다.

삼풍 백화점의 경우, 부실 공사에 대해 조금도 사죄하지 않고 고개를 빳빳하게 든 채 “건물이 무너졌으니 고객도 고객이지만 우리 회사도 막대한 손실을 입은 거야!”라고.. 정말 개념 안드로메다로 보낸 회장의 발언이 더욱 어그로를 탔었다. 정말 북괴 뺨치는 철면피 천하의 개쌍놈이 아닐 수 없다.
일본 같았으면 책임자가 할복을 해도 시원찮았을 일이다! 1985년 JAL123 추락 사고로 520명이 죽었을 때도, 별로 책임이 크지도 않은 정비사 한 명이 자살했잖아.
물론 지금은 피해자 보상하느라 삼풍 그룹 전체가 자산이 싹 압류당하고 진작에 공중분해되었으니 그들은 정말 최소한의 죄값은 치렀다.

이상이다.
우리나라 역사· 지리를 사랑하는 철덕이라면 양재 시민의 숲 역은 이렇게 볼거리가 많으니 꼭 답사해서 주변 시설들을 둘러보도록 하자.

아, 그나저나 여기 근처에 aT센터가 있고, 말로만 듣던 코스프레 오덕들이 공원에서 모임을 한 게 진짜 보였다.
그런데, 일본 오타쿠 복장을 하고서 윤 봉길 의사 기념관의 화장실에 갔다 오거나 근처를 들락날락하는 애들이 정서적으로 많은 논란이 된 바 있다.
옛날에, 일본 야동 업로드로 유명했던 김 본좌 양반도 최소한의 염치는 있어서 광복절에는 업로드 안 했다고 한다. =_=;; 정말 그런 애가 있다면 제발 개념 탑재 좀 했으면 하는 바람이 있다.

Posted by 사무엘

2013/11/02 08:26 2013/11/02 08:26
, , , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/894

1. 신분당선 양재 시민의 숲(매헌) 역

신분당선은 경부 고속도로를 따라 분당과 서울 강남을 16분 만에 잇는 민자 전철이다. 기본 요금이 수도권 전철의 일반 구간보다 700원이나 더 비싸지만, 속도가 충분히 빨라서 비싼 값을 하며 환승 할인도 되기 때문에 수요가 많다.

현재 개통해 있는 신분당선의 역들을 살펴보면, 강남(2호선), 도곡(3호선), 정자(분당)는 환승역이다.
판교는 판교 신도시 구간에 놓인 유일한 역이며 앞으로 성남-여주선과의 환승역이 될 예정이다. 신분당선 본사도 여기 인근에 있다.
여기 말고 서울 구간에 있는 비환승 신규역은 둘 있다. 하나는 등산 코스로 큰 각광을 받고 있는 청계산입구 역이다. 그리고 마지막 하나 남은 역은 잘 알다시피 '양재 시민의 숲' 역이다. 분당선에는 '서울숲'이라는 역이 있고 신분당선에는 '양재 시민의 숲'이라는 역이 있는 게 흥미롭다.

이 역은 서울의 강남구와 서초구 사이의 경계인 강남대로 상에 있다. 논현(7호선)부터 시작해 남쪽으로 내려가면 강남(2호선), 양재(3호선)의 순인데, 그 다음이 바로 양재 시민의 숲이다. 경부 고속도로 양재 IC 근처이고 현대· 기아 쌍둥이 사옥이 가까이 있기도 하다.
그렇잖아도 양재에서 끝나기에는 양재 역 이남에도 여러 중요한 시설들이 많이 있는데 이 역은 양재 역만 있었을 때의 2% 부족한 면모를 다소 보충해 주었다.

대표적인 예로 서울 교육 문화 회관이 있다.
2011년에 본인은 국어 정보 처리 시스템 경진대회에 참가했었고, 그때는 발표 심사와 시상식이 거기서 열렸다.
그때는 근소한 차이로 신분당선이 아직 개통하지 않았었기 때문에 회관에서는 양재 역에서 주기적으로 셔틀버스를 운행했다. 그걸 타고 회관으로 가야 했다.
그러나 지금은 신분당선이 생기면서 장소가 역에서 600m 남짓한 거리로 가까워졌기 때문에 아마 셔틀버스를 운행하지 않을 것이다.

이 역의 바로 옆에는 말 그대로 시민 공원으로 조성된 숲이 있다. 이 숲은 길을 사이에 두고 북부와 남부로 나뉘는데, 1번 출구로 나가면 북부 쪽으로 간다. 좁은 의미에서는 북부만을 양재 시민의 숲이라고 치는 듯하다.
그리고 5번 출구로 나가면 남부로 향하게 되며, '여의교'--여기가 여의도도 아닌데 이름이 왜 이럴까?--라는 개천 다리를 건너서 윤 봉길 의사 기념관 쪽으로도 갈 수 있다. 부역명이 괜히 윤 의사의 호인 '매헌'으로 정해진 게 아니다. 앞으로 소개할 각종 위령비들은 북부가 아닌 남부에 있다.

이런 관광 명소들이 여럿 있다는 게 잘 알려져 있기에, 본인은 하루 날을 잡아 지하철 정기권 떨이를 위해 일대 답사를 떠났다.
최 용신 기념관(안산선 상록수), 서대문 형무소 역사관(3호선 독립문) 가듯이 답사를 갔다.

2. 윤 봉길 의사

매헌 윤 봉길 의사 (1908-1932).

그는 중국 상하이의 훙커우 공원에서 열린 일본의 경축 행사장에 들어가서 참석자들이 일제히 묵념을 시작했을 때 용감히 폭탄을 던졌다. 천장절(쇼와 일왕 생일) 겸 상하이 사변 승리를 기념한 행사였다.
일본의 입장에서 이 정도로 뜻깊은(?) 행사장에다 폭탄을 터뜨림으로써 그는 유수의 일본군 장성들을 죽이거나 병신으로 만들었으며, 세계에 조선의 독립 의지를 알리는 데 성공했다. 립서비스 생색내기도 있었겠지만 중국의 장 제스 총통이 이 사건에 완전 반해서 극찬한 건 잘 알려진 사실이다.

사실, 그로부터 불과 3~4개월 전엔 일왕을 죽이려는 이 봉창 의사의 거사가 있었다. 그러니 일본은 이번 행사에서는 보안을 나름 강화하려 애썼고, 반대로 우리 쪽에서는 이번엔 불발하지 않게 정말 튼튼하게 폭탄을 만들려고 애썼다. 이 봉창과 윤 봉길이 사용한 폭탄을 만든 사람은 김 홍일 장군으로 동일 인물. (울산 자매 살인 사건의 가해자와 동명인 바람에 독립 운동가의 이름이 이미지가 다소 실추했다.)

일본은 보안 차원에서 행사장 입장객에게 초대장 검사를 실시하고, 도시락과 물통 외의 소지품은 반입하지 못하게 했다. 현장에서 식사는 제공 안 한다고 말이다.
그러나 그 시절이 X선 금속 탐지기가 쓰이던 시절은 아니었던지라, 우리 쪽에서는 폭탄 자체를 도시락과 물통 모양으로 만들어서 소지품은 통과 판정을 받았다.
초대장이 없는 건 윤 봉길이 시치미 뚝 떼고 유창한 일본어로 “아 왜 이런 기쁜 행사에 우리 자국민이 참석을 못 하냐?”라고 우겨서 넘겼다고 한다. 시쳇말로 '멘탈 갑'이어야 할 수 있는 일이다.

윤 의사는 물통 모양 폭탄이 성공적으로 터진 걸 확인한 후 도시락 모양 폭탄으로 자결하려 했다. 그러나 그 폭탄은 또 불발하여 실패했다. 그는 이내 일본 헌병에게 체포당했다. 자폭에 실패하고 죽지 못한 대가로, 잡힌 후엔 이 테러의 배후에 누가 있는지, 폭탄을 누가 만들어 줬는지 불라고 그야말로 온갖 악독한 고문을 당했을 것이다.

그는 일본 본토로 끌려가서 재판받은 뒤, 비공개로 집행된 총살로 겨우 24년간의 짧고 굵은 생을 마감했다.
일본은 감정 같았으면 이런 반동분자에게 능지처참을 가해서 시신을 본보기로 전시하고 싶었을지 모른다.
하지만 그렇게 공개 처형 즉결처분을 했다간 오히려 일제의 잔학함이 국제적으로 폭로되고 조선에 대한 여론이 좋아질 걸 우려해서 일을 조용히 해치웠다.

그 대신 윤 의사는 모 형무소 내부에 마련된 사형장에서 수십 발의 총알 세례를 받으면서 마치 차우세스쿠의 최후의 순간처럼 끔살당했다. 격발 중 일부는 윤 의사를 겨냥하지 않은 페이크였을지 모르나, 그래도 단 몇 발이라도 권총도 아니고 돌격소총으로 복부의 심장도 아니고 얼굴 미간을 집중적으로 맞았으니 형체가 남아나지 못하지 않았을까.

시신은 공동묘지 길 한복판에 표식도 없이 아무렇게나 암매장되었다. 그래도 안 중근과는 달리 해방 후에 유해가 수습· 송환되었으니 이는 매우 다행스러운 점이다. 백범 김 구가 이 봉창· 윤 봉길 같은 사람을 침투시키는 일뿐만 아니라 해방 후에 시신을 수습하는 일에도 최선을 다한 덕분이다.

윤 의사는 정말 가슴이 터질 듯한 얼마나 비장한 마음으로 훙커우 공원으로 가야만 했을까? 다음과 같은 유명한 말이 전해진다!

“사내 대장부는 뜻을 품고 집을 나서면 살아서 돌아오지 않는다.”

“너희도 만일 피가 있고 뼈가 있다면 반드시 조선을 위하여 용감한 투사가 되어라.
태극의 깃발을 높이 드날리고 나의 빈 무덤 앞에 찾아와 한 잔 술을 부어 놓으라.
그리고 너희들은 아비 없음을 슬퍼하지 말아라.
” (상하이 의거를 앞두고 아직 갓난아기인 두 아들들에게 미리 남긴 유언)

“이 시계는 선서식 후에 선생님 말씀대로 6원 주고 산 시계인데, 선생님 시계는 2원짜리이니 저와 바꾸어 주십시오. 제 시계는 앞으로 몇 시간밖에는 쓸 일이 없으니까요.” (김 구와의 최후의 만찬 자리에서)


저런 말과 글의 퀄리티를 보노라면, 누가 윤 의사를 감히 무식한 테러리스트 정도로  생각하겠는가?
게다가 유언을 보면 '빈 무덤'이랜다. 그는 최악의 경우 자기 시체도 못 찾게 될 수도 있다는 것까지도 다 염두에 둔 듯하다. 아아...
자, 배경지식에 대한 복습은 이 정도로 마치고, 이제부터 기념관과 주변 지역 사진을 늘어놓도록 하겠다.

3. 윤 봉길 의사 기념관

사용자 삽입 이미지

기념관을 정면에서 본 모습이다. 입장은 무료이나, 주차장은 무료가 아니다. (박 정희 기념 도서관은 둘 다 무료였던 걸로 기억.)
윤 봉길 의사 기념관의 경우, 재정난· 운영난 때문에 유품들이 제대로 관리도 못 되고 기념관 자체가 폐관될 위기에 처했다고도 들었다. 차라리 입장료를 받아서 유료화를 해도 좋으니 부디 그런 일이 일어나지 않기를 바란다.

기념관은 중앙 홀의 좌우로 방이 2개 있었다. 내부의 관람 컨텐츠는 이게 전부다. 2층과 3층이 있긴 하지만 거기는 관람 공간이 아님. 3층의 경우, 기념 사업회의 수익 모델 차원에서 강당 공간 유료 대여를 한다고 한다.
안에는 윤 의사의 여러 사진, 유품들이 전시되어 있고 어록이 소개되어 있었다. 윤 의사를 소재로 초등학생들이 포스터를 그린 것도 잔뜩 걸려 있었다.

여기가 첫 개관한 건 1988년으로, 천안의 독립 기념관보다 살짝 늦지간 그래도 비슷한 시기에 개관한 셈이다.
참고로 윤 의사의 고향인 충남 예산에도 별도의 윤 의사 생가와 기념관이 있긴 하다고 한다.

사용자 삽입 이미지

이것도 윤 의사의 생애에서 유명한 일화다. 한자를 못 읽는 어떤 문맹 청년이 윤 의사에게 자기 아버지 묘비를 좀 찾아 달라고 동네 야산의 묘비들을 죄다 뽑아 왔는데...
“님 선친 묘비는 골라 낼 수 있지만, 묘비들 원상복귀는 어떻게 시킬려고?”라는 한 마디에 데꿀멍해 버린 사연 말이다. 머리가 나쁘면 손발이 개고생한다. 그 청년은 자기뿐만 아니라 남의 묘지도 못 찾게 만드는 초대형 민폐를 달성했다. -_-;;

안 중근도 그렇지만 윤 봉길도, 테러리스트(?)이기에 앞서 민족 독립의 길을 장기적인 안목에서 진지하게 생각했던 사상가이고 계몽가였다. 윤 봉길의 삶에서도 의외로 최 용신스러운 면모를 많이 발견할 수 있다. 그렇게 교육자의 길을 갈 수도 있었던 지식인이 얼마나 고민하던 끝에 폭탄까지 들게 됐을까. 깊이 생각하지 않을 수 없다..

(下에서 계속됨)

Posted by 사무엘

2013/10/30 08:23 2013/10/30 08:23
, , , , , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/892

행렬 기초 이야기

a*x + b*y + M = 0
c*x + d*y + N = 0

이라는 두 개의 이원(x, y) 일차방정식이 있다고 치자. 흔히 연립방정식이라고도 불린다.
이 방정식을 풀려면 x, y 중 하나의 계수를 a나 c, 아니면 b나 d로 맞춰 줘서 한 변수를 소거해야 한다. 그래서 일원 일차방정식으로 바꿔서 반대편 변수의 근을 구한 뒤, 그 값을 대입하여 원래 변수의 근까지 구하면 된다.

이를 일반화하여 위의 방정식의 '근의 공식'을 구하면 다음과 같다. 뭔가 규칙성이 있는 것 같으면서도 미묘하게 잘 안 외워진다.

x = (N*b-M*d) / (a*d-b*c)
y = (N*a-M*c) / (a*d-b*c)

분모를 보니 생각나는 게 없는가?
그렇다. 이것은

[ a b ]
[ c d ]

라는 원소로 구성된 2*2 정방행렬의 행렬식을 구하는 공식이다.
이 행렬식의 값이 0이라는 건 a:b와 c:d의 비율이 동일하다는 뜻이다. 따라서 이 행렬을 구성하는 벡터들은 서로 일차(선형) 독립을 이루지 못하며, 상수항이 어떻냐에 따라서 이 방정식은 근이 무수히 많거나 근이 존재하지 않게 된다.

이런 행렬을 거친 일차변환은 2차원 평면을 1차원 선이나 점으로 찌그러뜨린다. 이런 행렬은 영벡터(모든 원소의 값이 0)가 아닌 벡터 중에서도 자신과의 곱을 영벡터로 만드는 물건이 무수히 존재하게 된다(Ax=O).
예를 들어 연립방정식 x+2*y = 0 과 3*x+5*y = 0의 근은 x와 y가 모두 0인 trivial solution 단 하나밖에 없으나, x+2*y = 0과 3*x+6*y = 0은 두 식이 동치나 마찬가지이기 때문에 x = -2*y이기만 하면(가령 2와 -1) 식이 성립한다. non-trivial solution들이 존재한다는 뜻이다. 결국, 근이 무수히 많을 수 있다는 말과 본질적으로 동일하다.

이들은 모두 필요충분조건 관계에 있으며, 이외에도 이런 행렬의 엄밀한 특성에 대해서는 선형대수학 시간에 많이 배우게 된다.

말이 길어졌는데, 그럼 변수가 세 개 이상이 되면 근을 구하는 양상이 어떻게 바뀔까?
그야말로 폭발적으로 복잡해진다.

변수가 2개일 때는 x, y 근에 최대 두 변수의 곱(최대 2차)으로 이뤄진 항이 분자와 분모에 2개씩 있었다.
그러나 3개일 때는 세 변수의 곱으로 이뤄진 항이 분자와 분모에 6개씩 들어간다.
그리고 이를 일반화하면, n원 1차 연립방정식의 근은 n개의 변수의 곱으로 이뤄진 항이 분자와 분모에 무려 n! (팩토리얼)개씩 들어간다!
이것이 '폭발적'이라는 단어의 의미이다. 예를 들어,

[ a b c ]
[ d e f ]
[ g h i ]

라는 3*3 정방행렬의 행렬식은 다음과 같다. 어떤 규칙성이 있는지, 어떻게 하면 잘 외울 수 있겠는지 한번 생각해 보시라.;;

a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g

a가 속한 행과 열을 제낀 2*2 행렬(e f / h i)의 행렬식에다가 a를 곱해서 더하고,
다음으로 b가 속한 행과 열을 제낀 2*2 행렬(d f / g i)의 행렬식에다가 b를 곱해서 빼고,
끝으로 c가 속한 행과 열을 제낀 2*2 행렬(d e / g h)의 행렬식에다가 c를 곱해서 더하면.. 이 행렬 전체의 행렬식이 나오긴 한다. 2*2 행렬식이 2개의 항으로 구성돼 있는데 그런 식이 3개가 늘어나니 총 6개가 되는 게 맞다.

이런 방식으로 행렬을 쪼개면 그 어떤 크기의 행렬의 행렬식도 구할 수는 있다. 하지만 크기가 3을 넘어가는 행렬에 대해 행렬식 내지 방정식을 푸는 일반적인 공식을 구하려는 생각은 포기하는 게 좋다. 머리 터진다..;;

참고로 1변수 n차 방정식의 경우를 생각해 보자. 2차 방정식은 잘 알다시피 비교적 외우기 쉬운 근의 공식이 존재하는 반면 3차와 4차는 근의 공식이 있기는 하나 인간의 머리로 도저히 외울 수 없을 수 없을 정도로 미치도록 복잡한 형태이다. 게다가 서로 인접한 차수끼리 규칙성 같은 것도 아예 존재하지 않는다. 5차 이상부터는 대수적인 방법만으론 깔끔하게 풀 수조차 없다.
그에 반해 n변수 1차 연립방정식은 비록 그 정도로 카오틱하게 복잡한 건 아니지만, 그래도 좀 다른 양상으로 복잡해진다는 게 오묘한 점이다.

그리고, 이건 일반적인 공식을 구하려 할 때 딸려 나오는 식이 지수함수 급으로 복잡해진다는 소리다. 일반적인 경우가 아니라 그때 그때 특정 숫자가 주어진 행렬의 행렬식을 구하는 알고리즘의 시간 복잡도가 지수함수라거나 NP 완전 문제 급이라는 뜻은 아니다. 둘은 서로 다른 개념이다.

변수가 3개를 넘어가는 방정식은 어떻게 풀어야 할까?
가령, 변수가 x, y, z라고 치면 일단 모든 방정식의 x의 계수를 1이든, 맨 위의 식의 계수로든 어쨌든 하나로 일치시켜야 한다. “등식에서 같은 수를 더하거나 빼도 등식은 성립한다.” / “등식에서 같은 수를 곱해도 등식은 성립한다” 라고.. 초등학교 산수 시간에 배우는 지극히 당연하고 기본적인 원리를 이용해서 방정식을 푸는 것이다.

그렇게 해서 x 변수를 없는 놈 취급할 수 있게 만든 뒤, 다음 방정식에 대해서 y 변수의 계수를 일치시킨다.
이런 절차를 반복하여 변수를 z만 남겨서 z 값을 구하고, 다음으로 y, x의 순으로 재귀적으로 근을 구하면 된다.
행렬이라는 물건 자체가 이런 연립방정식을 푸는 동작을 간략하게 모델링하는 과정에서 고안되었다.
앞서 말한 절차를 행렬 용어로 표현하자면, 가우스-조던 소거법으로 행렬을 대각화하는 것과 같다.

행렬이 대각화가 되고 나면 방정식을 다 푼 것이나 다름없을 뿐만 아니라, 행렬식의 값은 그 행렬의 대각선 원소들의 곱으로 쉽게 구할 수 있게 된다.
행렬을 대각화하는 데 드는 시간 복잡도는 일반적으로 O(n^3)으로, 행렬 곱셈의 비용과 같다.
이 작업을 숫자를 대상으로 곧장 곧장 업데이트하는 게 아니라, 기호를 이용해서 일반적인 경우를 다 고려하여 표현하려다 보면 항 개수가 아까 같은 팩토리얼 급으로 증가하게 되는 것일 뿐이다.

연립방정식 하니까 응용수학 내지 산업/경영공학 같은 데서 다루는 그 이름도 유명한 선형 계획법(LP)이 생각난다.
이런 데서 다루는 문제는 대체로 변수의 개수가 식의 개수보다 더 많고, 식도 등식이 아니라 부등식이다. 애초에 해 자체는 무한히 많을 수밖에 없는데 그래프의 능선을 따라다니면서 주어진 조건을 최대한 만족하는 영역을 찾는 게 목적이다. 이런 문제는 실용적인 가치도 무진장 높다.

이런 걸 푸는 제일 간단한 알고리즘으로는 simplex method가 있는데, 그 이상의 디테일은 본인도 비전공자인 관계로 잘 모른다. 변수의 차원이 최대 2차원 정도일 때나 그래프를 그려서 생각할 수 있지, 이 역시 3차원 이상으로 가면 머리에 쥐 난다. 고등학교에서 행렬을 2*2까지밖에 다루지 않는 것, 그리고 전산학에서 간단한 bool 대수 연산을 다룰 때 변수를 3개까지밖에 넣지 않는 게 다 이유가 있어서 그런 것이다.

Posted by 사무엘

2013/10/26 19:25 2013/10/26 19:25
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/891

오늘은 판문점과 관련하여 안보 지리 역사 이야기를 늘어놓겠다.
다음은 판문점 주변의 구글어스 사진이다. 이 글 전체를 이해하는 데 필요하므로 별도의 창에다 열어 놓으시기 바란다.

사용자 삽입 이미지

요즘 세상은 참 대단하긴 하다. 이런 봉인된 장소도 항공 사진을 다 볼 수 있고, 사실 올해(2013) 초부터는 구글어스에 북한, 특히 평양의 세부 지리 정보까지 다 뜨기 시작했으니 말이다.

공동 경비 구역(JSA)이라는 말을 들어 보셨을 것이다.
먼 옛날, 북한이 일으킨 6·25 전쟁으로 인해서 우리나라와 북한은 서로 치유가 거의 불가능한 상처를 입었고, 분단은 완전히 굳어졌으며 상대방에 대한 불신과 적개심은 극도로 커졌다.

그런데 이렇게 영토가 양분된 상태로는 서로 왕래가 전혀 불가능하다 보니 당장 휴전 협정조차 할 수 없었다.
그래서 대한민국 내부이긴 하나 정치적으로 남한 관할도 북한 관할도 아니고 UN이라는 제3자가 중립적으로 관할하는 지역이 필요해졌으며, 판문점이라는 주막이 있던 지역 일대가 그런 구역으로 설정되었다.

사용자 삽입 이미지

옛날에는 주변이 이렇게 허허벌판이었지만 훗날 건물 주변에 전부 풀과 나무가 조성된 듯하다. 지금의 구글어스 항공 사진과 몹시 비교된다.

자, 그럼 이제부터 구글어스 사진에서 우측 하단을 주목하시기 바란다.
가장 좁은 의미에서 판문점은 아무래도 흰색+파란색 지붕 형태로 도열해 있는 아담한 회의장 건물 7개이다. 얘들은 남한과 북한 영토에 반반씩 걸쳐서 만들어져 있다.
하지만 판문점의 주변 시설은 그게 전부가 아니다. 그로부터 남한 쪽에 있는 커다란 건물은 '자유의 집'이라고 불리고, 그로부터 남쪽에 있는 연보라색 지붕의 건물은 '평화의 집'이라고 불리는 일종의 프레스센터이다.

더 남쪽에 있는 칙칙한 건물은 군용차 형상만 봐도 짐작할 수 있듯, 병영이다. 판문점 주변엔 온통 병사가 경비하는 초소가 늘어서 있다.
그리고 이렇게 건물들이 있는 곳의 오른쪽을 보면 도로가 아니면서 수풀도 없는 공터가 있는데, 거기는 헬리콥터 이착륙장이다. (본인이 분홍색 글씨로 1번이라고 표시한 곳) 저 옛날 사진에서 헬리콥터가 있는 곳과 동일한 지점일 것이다.

다음으로, 판문점에서 북한 쪽을 살펴보겠다.
회의장 바로 이북에 자리잡은 회색 지붕의 직사각형 건물은 '판문각'이다. 남한의 '자유의 집'에 대응하는 건물이라 하겠다. 그리고 좀 더 북쪽으로 멀리 떨어진 밝은 옥색 건물은 '통일각'이다. 나머지 건물들은 역시 병영이나 기자 대기실이다.

공동 경비 구역은 군사 분계선 이남과 이북에 있는 남한과 북한의 비무장 지대를 두루 포함하고 있다. 그리고 이 안에서는 말 그대로 남한 및 UN군 초소와 북한군 초소도 뒤섞여 있다.
남양주 종합 촬영소에는 판문점 세트가 있는 걸로 잘 알려져 있다. 거기 항공 사진을 보면 알 수 있듯, 재연해 놓은 시설은 회의장과 판문각 정도이다.

영화 <튜브>가 김포 공항 청사 하나를 빌려서 총격전을 촬영했다고 하지만, 판문점 주변은 영화 촬영용으로 도저히 점거할 수 없는 곳이다. 영화는 아무래도 세트장에서 찍는 게 불가피하다.
하지만 진짜 판문점과 세트 판문점은 판문각 주변의 경치가 아무래도 차이가 있다. 그렇기 때문에 항공 사진을 눈썰미있게 보고 나면 주변 사진을 보고 여기가 진짜인지 세트인지를 분간하는 게 가능하다.

여기는 민통선 수준이 아니라 군사 분계선에 바싹 근접한 몹시 중요하고 위험한 곳인 관계로, 국내에서는 VIP 급의 높으신 분이 아니면 개인 방문은 불가능하다. 오로지 30인 이상 45인 이하의 단체 견학만이 가능하며 방문 예정일보다 꽤 오래 전에 신청을 해서 허락을 받아야 한다. 갔다 온 사람들의 블로그 후기를 보면, 내부 사진 촬영은 의외로 자유로은 듯.
엄연한 우리나라 영토인데 UN 사령부의 허락을 받으면서 아주 까다로운 절차를 거쳐서 드나들어야 하는 게 비극임은 틀림없다.

이제 판문점의 서쪽으로 가 보자.
두 길이 합류하는 광장이 있고 광장 중앙에는 자그마한 풀밭이 보일 것이다.
더 서쪽으로는 '사천'이라는 자그마한 개천 위에 놓인 다리가 있는데, 이 다리를 건너면 북한이다. (분홍색 글씨 4번)
이 다리는 국토 분단 전부터 있었지만 훗날 남한과 북한 국경을 가르는 다리가 되고 말았고, <돌아오지 않는 다리>라는 이름이 붙었다. 영어로도 말 그대로 bridge of no return이다.

예전에는 이 다리가 북한 사람들이 판문점으로 오는 유일한 길이었다. 이 다리를 통해 6·25 전쟁 말에 포로 송환이 이뤄졌고, 마지막으로는 1968년 푸에블로 호 선원들이 석방될 때 이 다리를 건넜다. 당연히 남으로든 북으로든 한번 다리를 건넌 뒤부터는 반대편 국가로 돌아갈 수 없으니 다리의 이름은 정서적으로 적절하게 붙여졌다. 원래 이 다리의 이름은 <널문다리>였다고 한다.

그런데 그 후 대형 사건이 터졌다.
이름하여 1976년 8월의 판문점 도끼 만행 사건.

지도를 보면, 판문점의 서쪽에 UN사령부 소속의 '제5 관측소'가 있다 (분홍색 글씨 2번). 항공 사진으로는 잘 안 드러나 보이지만 저기는 언덕 위이다.
그리고 <돌아오지 않는 다리>의 남한 방면 말단에는 UN사령부 소속의 '제3 초소'가 있다 (분홍색 글씨 3번). 건너편에는 물론 북한 '제4 초소'가 있고 말이다.

사용자 삽입 이미지

옛날에는 UN사 제5 관측소와 UN사 제3 초소 사이의 표시 지점에, 커다란 미루나무가 한 그루 서 있었다 (분홍색 글씨 5번). 그래서 언덕 위의 제5 관측소에서 제3 초소 내지 <돌아오지 않는 다리> 일대를 감시하는 데 어려움이 있었다. 그렇잖아도 북한은 제3 초소에서 근무하는 UN사 소속 병사들에 대해 납치 시도를 여러 번 했다고 한다.

결국 UN사 소속의 미군 장교와 병사, 그리고 여기에 소속된 근로자들이 미루나무를 베어내기로 했다. 그러나 북한은 자신을 더 수월하게 감시하려는 이런 시도를 달가워하지 않았다. 그 당시 공동 경비 구역에는 UN군이고 북한군이고 사람들이 비교적 자유롭게 드나들 수 있었기 때문에, 북한군은 각종 딴지와 협박을 걸면서 작업을 방해했다.

8월 6일에 이미 근로 부대 소속의 근로자와 경호원들이 한번 퇴짜를 맞고 쫓겨난 적이 있었기에, 8월 18일에는 나무의 줄기 대신 가지만 치기로 하고 작업이 재개되었다.
그러나 이 때 비극이 시작됐다.

북한군은 이번에도 작업을 방해하고 딴지를 걸더니, 나중에는 갑자기 수십 명의 병사들을 데려 와서는 작업 책임자이던 군인들에게 무차별 폭행을 가하기 시작했다 (JSA 내부엔 소총을 들고 들어오지는 못하니까). 특히 미군 보니파스 대위와 바레트 중위를 참혹하게 살해하고 말았다. 겁먹은 근로자들이 도망치면서 버린 도끼로 싸이코패스마냥 사람 얼굴을 마구 찍고 난도질했다. 이들은 얼굴이 형체를 알아볼 수 없는 피투성이가 된 채 끔살당했다.

사실, 이때 북한군은 “무고한 남조선 로동자들은 놔 두고, 미 제국주의 원쑤들에게 집중적으로 본때를 보여 주라”라고 상부로부터 지령도 받은 상태였다. 물론, 그렇다고 해서 한국인 부상자가 없던 것은 아니었지만.
그러고도 북한은 우리는 정당방위를 했을 뿐이며 이게 다 판문점 일대에 긴장을 조장하려 한 너희들 잘못이라고, 안하무인과 적반하장의 극치의 개념 안드로메다 태도를 보였다.

이에 박 정희 대통령은 그 유명한 “미친 개에겐 몽둥이가 약이다”라는 희대의 명언을 남겼다. 아울러 “내 군화와 철모를 당장 가져오라!”라는 말까지도 전해진다.
더구나 선전포고 급의 도발로 인해 젊은 장교를 둘이나 어이없게 잃은 미국은 정말 제대로 빡쳤다.

그 결과, 우리나라는 휴전 이후 최초로 데프콘(경계 준비 태세) 3이 떨어졌다. 참고로 북한의 위협이 전혀 없는 완전 평시가 5, 그리고 현재 우리나라의 레벨은 4이다. 3이 되면 한미 연합 사령부에 작전권이 넘어가고 전군의 휴가· 외출이 통제된다. 우리나라 역사상 데프콘 3이 떨어진 때는 저 때와 1983년의 아웅산 묘소 폭탄 테러 때 단 두 번뿐이었다.

그리고 8월 21일.
미국의 전설적인 나무꾼의 이름을 따 '폴 번연 작전'이 시행되었다.
미국 본토에서 수십 대의 전투기와 폭격기가 날아와서 한반도 상공을 배회했다. 그리고 바다에는 항공모함까지 와서 북한 해역을 기웃거리면서 무력 시위를 벌였다.

문제의 구역엔 특전사 소속의 수십 명의 무장 병사들이 들이닥쳤다. JSA 내부에서는 권총 이상의 무기를 휴대해서는 안 되지만 아랑곳하지 않고 M16 소총, 수류탄, 크레모아 등 살상 무기들이 즐비했다. 이들의 엄호를 받으면서 작업이 재개된 끝에, 문제의 미루나무는 가지치기 정도가 아니라 밑동만 남긴 채 완전히 베여 나가고 말았다. 아래의 before - after 사진을 보시라.

사용자 삽입 이미지사용자 삽입 이미지

그리고 이 작전 수행 중에는 경비 레벨이 데프콘 3이던 게 아예 전군에 실탄이 지급되는 데프콘 2로 올라갔다!
아마 인류 역사상 제일 살벌한 나무 베기 작업?작전으로는 다섯 손가락 안에 들어가지 싶다.

이런 무력 시위는 단순한 나무 베기 이상으로 북한을 낚으려는 의도도 있었다.
만약에 북한이 아직도 분위기 파악을 못 하고 총을 한 발이라도 쏘면서 도발에 응할 경우, 이 미군 병력으로 JSA에서 얼쩡거리던 북한군들을 모조리 섬멸하고 아예 북한 본토를 폭격해서 군사 분계선을 북쪽으로 올려 버리겠다는 계획이었다.

이런 미국의 초강수에 결국 북한은 깨갱 했다. 아무리 중국과 소련이 북한과 친하다지만 이 사건에서만큼은 그들도 북한을 편들 수 없었다. “이건 아무리 생각해도 니가 병신 인증을 한 거니 빨랑 미국한테 사과나 해라”였다.
김 일성은 내부적으로 '북풍 1호'를 발령하여 전군을 무장시키고 대비는 했지만, 기본적으로 버로우 타고 무력 시위와 도발에 절대로 응하지 말라는 명령을 내려서 미국을 달랬다. 그리고 자신이 직접 나서서 유감을 표명하고 아주 형식적으로나마 사과함으로써 사태를 겨우 수습시켰다.

이 사건을 계기로 JSA 내부에도 군사 분계선 경계가 확실하게 생겼다. 도끼 만행 사건 이전에는 판문점 회의장 안까지 칼같이 남북 금이 그어져 있는 수준은 아니었으며, 남한 쪽에 속한 JSA에 북한군 초소도 있기도 했다. 그러나 그 후로 금이 그어졌고 그쪽의 북한군 초소는 모두 파괴· 철거되었다. 요컨대, 아래와 같은 사진은 판문점 도끼 만행 사건의 결과물이라는 뜻 되겠다.

사용자 삽입 이미지

그리고 결정적으로 <돌아오지 않는 다리>는 폐쇄되어 남북 사람들이 오가는 용도로 쓰이지 않게 되었다.
이에 북한은 <돌아오지 않는 다리>를 거치지 않고 판문점으로 가는 길을 트기 위해 북쪽에 자기네만 쓰는 다리를 또 만들었는데, 이것이 바로 사흘 만에 뚝딱 건설되었다고 하여 <72시간 다리>라고 불린다. 구글 지도에서 북쪽으로 노란색 음영이 쳐진 길이 경유하는 다리이다.

판문점의 역사에 대해 얘기하면서 도끼 만행 사건은 절대로 빠질 수 없는 아이템이 되고 말았다.
북한의 잔학· 흉악함을 부각시키기 위해 사건의 이름에다 '도끼'라는 이름이 절대로 빠지지 않는다. 영어로도 tree cutting incident뿐만 아니라 axe murder incident라고도 불린다.

참고로 밑동만 남았던 그 문제의 미루나무는 나중에 아예 뿌리째 완전히 뽑혀 없어졌다. 언제 그렇게 된 건지는 잘 모르겠지만, 어쨌든 그 자리에는 현재 간단한 위령비만이 세워져 있다. 그렇기 때문에 구글어스에도 가로수를 암시하는 흔적이 나타나지 않은 것이다.

사용자 삽입 이미지


Posted by 사무엘

2013/10/23 08:29 2013/10/23 08:29
, , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/890

« Previous : 1 : ... 132 : 133 : 134 : 135 : 136 : 137 : 138 : 139 : 140 : ... 215 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  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        

Site Stats

Total hits:
2681287
Today:
1248
Yesterday:
2123