« Previous : 1 : ... 20 : 21 : 22 : 23 : 24 : 25 : 26 : 27 : 28 : ... 31 : Next »

비주얼 C++ MFC의 역사 -- 下

현재 윈도우 운영체제의 GUI는 잘 알다시피 윈 2000/ME까지 유지되던 고전 테마, 그리고 XP 테마와 비스타/7 테마가 서로 따로 논다.
MS 오피스도 XP/2003/2007이 따로 놀고,
거기에다가 비주얼 개발툴의 디자인도 2005/2008/2010이 다 달라진다.

어디 그뿐인가. 현재 운영체제의 configuration에 따라 테마가 나타나는 모양도 달라져야 한다. 가령, 오피스 2003은 전반적으로 파란 색상이지만 운영체제가 회색 고전 테마일 때는 은색이 깔림. 그 반면 오피스 2007은 독자적인 배색 컨셉이기 때문에 운영체제의 상태에 관계 없이 여전히 은은한 하늘색 색상이 되는 게 맞다.

이런 세세한 알고리즘은 reverse engineering이라도 해서 알아내야 할 텐데, GUI 툴킷 만드는 일은 정말 장난 아니게 어려울 것 같다. 아래아한글의 스킨을 개발하는 팀도 고생 무지하게 했을 거라는 생각이 든다. 차라리 운영체제 GUI를 완전히 생까던 9x  시절이나, 반대로 잠시 100% 운영체제 표준 GUI만 따르던 워디안 시절이 나았겠다.

자, 이렇게 GUI 비주얼들이 난립하고 기존 MFC는 이런 수요를 충족하지 못한 채 시간만 자꾸 흐르고 있었다. 그러던 차에 MS는 결단을 내렸다. 바로 비주얼 C++ 2008 플러스 팩. MFC42 시절 이래로 MFC에 대대적으로 기능을 추가하여 역대 오피스와 비주얼 툴들의 UI, 그리고 심지어 리본 UI까지 MFC에다 넣어 줬다.

MFC의 새단장 소식이 전해지던 당시, 많은 개발자들은 MS가 자기네 오피스 팀이 개발한 오리지널 GUI 소스를 리팩터링해서 전해 줄지 무척 기대했었다. 하지만 아쉽게도 그건 아니고, 이미 BCG라는 러시아 회사에서 개발하여 판매 중이던 제3자 라이브러리를 MS라는 브랜드만 넣어서 제공하는 형태가 되었다. MS의 GUI는 MFC를 써서 개발된 것도 아니고, 모듈 구조를 보아하니 외부에 선뜻 떼어 줄 만한 상태가 아닌 모양이다.

이 작업의 결과로 MFC DLL은 덩치가 정말 크고 아름다워져서, 1MB 초반이던 게 4MB를 훌쩍 넘어갔다. CWinApp, CFrameWnd는 새로운 GUI 기능과의 연동을 위해, Ex라는 접미사가 붙은 CWinAppEx, 그리고 CFrameWndEx라는 파생 클래스가 추가되었다.

그런데, MS가 제3자 중에서도 왜 하필 BCG 라이브러리를 선택했는지에 대해서 불만을 제기하는 사람이 있다. 김 민장 님이 굉장히 옛날에 쓰신 개념글을 하나 읽어보자.

일단, 한눈에 BCG 제품의 메뉴 폰트가 한 픽셀 작음을 알 수 있다. 메뉴뿐만 아니라 툴바 아이콘도 가로 폭이 1픽셀 작은 것 같고, "Solution Explorer"의 글씨도 작다. (중략) 데모 프로그램 다운 받고 단 3분 동안 들여다 봤는데도 벌써 이상한 점 서너 개가 나왔다. 그러니 BCG 제품을 믿지 못하겠고 사용하기가 꺼려지는 것이다.


특히 메뉴의 글씨의 크기가 작은 것은 비주얼 C++ 2008/2010에서까지 그대로 이어져 오고 있는 걸 본인 역시 확인했다. 이건 꽤 심각한 문제인데? (왼쪽이 good, 오른쪽이 bad)

사용자 삽입 이미지사용자 삽입 이미지
도대체 왜 이렇게 동작하는 걸까? 궁금해서 MFC의 소스를 들여다봤다. 내가 발견한 문제점은 두 가지이다.

afxglobals.cpp를 보면 MFC의 GUI 구성요소들이 한데 공유하는 GDI 오브젝트들이 한데 모여 있으며, 그 중에는 글꼴 오브젝트도 응당 있다. 그런데 여기 생성자를 보면,

m_bUseSystemFont = FALSE;

로만 되어 있고, SystemFont라고 MFC 소스 전체를 검색해 봐도 이 값을 바꾸는 멤버 함수 같은 건 어디에도 나오지 않는다. 메뉴의 글씨체는 운영체제의 시스템 글꼴로 나오는 게 일반인데(한글 윈도우의 고전 테마에서는 그냥 ‘굴림’처럼), 저게 TRUE가 아닌 FALSE인 한은 운영체제 한글 윈도우 고전 테마 + 오피스 구버전 테마 모드에서도 메뉴의 글꼴은 Segoe 내지 Tahoma로 자기의 독자적인 글꼴로 출력된다.

그리고 더 큰 문제는 UpdateFonts 함수에 있다. Adjust font size라는 주석 하에

if (nFontHeight <= 12)
    nFontHeight = 11;

라는 글꼴 보정 코드가 있다. 그런데 이 잘못된 보정 때문에 BCG 툴킷이 정상보다 글씨가 작게 찍힌다. 도대체 이 코드가 왜 들어갔는지 모르겠다. 12픽셀이던 걸 11픽셀로 줄이면, 한글· 한자가 가장 잘 찍히는 9포인트보다 글자 크기가 한 단계 더 작아져 버린다. 아마 영문 오피스 2007의 글꼴이 여타 비주얼에도 획일적으로 적용되는 듯하다.

한눈에 봐도 MS 원본 프로그램과는 UI가 다르게 찍히는 GUI 툴킷을 최소한의 보정도 없이 MS가 자기 이름으로 어떻게 MFC에다 내장시켜서 내놓은 걸까? 물론 이런 시도조차 없는 것보다는 낫지만, 역시 네이티브 C++ 개발자로서 꽤 안타까운 일이다. 차라리 제3자 라이브러리 시절에는 소스를 고쳐서 라이브러리를 새로 빌드할 수라도 있지만, 그 거대한 MFC의 내부에 내장이 되어 버린 코드는 고칠 수도 없는 노릇이고.

김 민장 님의 블로그에 나와 있듯, BCG보다는 Codejock이라는 미국 회사에서 개발한 Extreme Toolkit이라는 GUI 라이브러리가 원본과의 고증(?)이 더 잘 돼 있고 품질이 좋다고 그런다.

이렇듯, MS는 자기네가 처음으로 구현한 기능을(뭐, 오피스 팀이니, VS 팀과는 다른 부서이지만) 외부 회사로부터 구현체를 사 오는 기묘한 방법으로 집어넣어서 MFC를 확장했다. 일단 MS 내부에서 MFC를 자기네 프로그램의 개발에 거의 안 쓴다는 점을 염두에 둘 필요가 있겠다. -_-;; 진짜로 워드패드와 그림판을 빼고는 거의 없다.

본인 역시 일단 중요 제품인 <날개셋> 한글 입력기를 MFC 없이 순수 API + 간단한 싸제 라이브러리만으로 개발하기 시작했으니, MFC와는 직접적으로 결별했다. 하지만 C++과 윈도우 플랫폼이 살아 있는 한, MFC의 중요성과 의의는 그리 금방 격하되지 않을 것이다.

다만, 덩치가 커져도 너무 커져 버린 건 진짜로 아쉬운 점이다. 그렇게 살이 뒤룩뒤룩 찐 네이티브 환경을 쓰느니, 차라리 훨씬 더 생산성 좋은 닷넷이 그 역할을 조금씩 대체하고 있는 게 아닐까 싶다.
그리고 여담이지만, 윈도우, 오피스, VS는 앞으로도 또 비주얼이 완전히 확 바뀌는 일이 있을지 궁금하고 기대-_-되기도 한다. ^^

Posted by 사무엘

2012/03/29 09:10 2012/03/29 09:10
, ,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/661

비주얼 C++ MFC의 역사 -- 上

옛날에 비주얼 C++의 역사에 대해서는 거창한 글을 쓴 적이 있는데 MFC 자체에 대해서는 의외로 블로그 개설 이래로 글을 쓴 적이 없었던 것 같다. 그래서 오늘은 이 주제로 한번 칼럼을 써 보겠다.

MFC는 잘 알다시피 C 언어 기반인 윈도우 API를 C++로 얇게 포장하는 한편으로, C++의 특성을 살려 더욱 생산성 있고 편리한 윈도우 응용 프로그램 개발을 목표로 만들어진 C++ 라이브러리이다. C 언어로 API만 쓸 때에 비해 네이티브 코드 프로그램 개발이 넘사벽급으로 훨씬 더 편리해진다는 건 부인할 수 없는 사실이다(특히 message map 덕분에! ㅋㅋ).

이것의 역사는 윈도우 3.x 시절이던 1992년 무렵으로 거슬러 올라간다. 이때는 MS의 주력 운영체제가 도스에서 윈도우로 바뀌고, 주 개발 언어가 C에서 C++로 이제 막 바뀌던 매우 중요한 과도기였다. 당시 볼랜드의 터보 C의 인지도에 압도적으로 밀리고 있긴 했지만, 마이크로소프트도 MS C라는 컴파일러를 개발해서 팔고 있었고, 이게 7.0 버전부터는 C++ 언어도 지원하기 시작했다.

MFC는 바로 MS C/C++ 7.0부터 도입되었으며, 그 다음부터는 제품명이 그 이름도 유명한 비주얼 C++ 1.0으로 바뀌게 되었다. 당시에는 라이브러리에 Microsoft Foundation Classes라는 거창한 정식 명칭이 없었기 때문에, 그냥 Application Frameworks라고 불렸다. 이것이 바로 AFX의 어원이다.

그래서 오늘날까지도 MFC의 핵심 인클루드 파일 이름은 mfc.h가 아니라 afx.h / afxwin.h이다. 또한 AfxGetApp(), AfxMessageBox() 같은 함수명과, AfxWnd##, AfxFrameOrView##처럼 MFC가 자체적으로 생성하는 윈도우 클래스 이름에도 AFX라는 약어를 찾을 수 있다.

비록 16비트 시절부터 존재하긴 했지만 MFC가 본격적으로 볼랜드 사의 컴파일러와 걔네들 라이브러리를 누르고 인기를 누리기 시작한 건 32비트로 넘어오면서이다. MFC가 첫 도입되었을 때는 C++ 개념을 구현하는 데 드는 특유의 오버헤드가 성능 면에서 문제가 되지 않을까 하는 회의적인 시각이 많았었다. 가령, code bloat으로 인한 용량 증가를 비롯해, 가상 함수 호출이라든가, 윈도우 핸들을 C++ 개체로 연결하기 위한 비용 같은 것 말이다.

워낙 옛날에, C++이 지금과 같은 규격으로 확장되기 전에 개발되던 것이다 보니 MFC는 RTTI를 자체적인 메커니즘으로 구현했으며, 컨테이너 클래스를 템플릿 없이 자체적으로 여러 구현체로 만든 게 있다. CPtrList, CObList 같은 것 말이다. MFC가 처음 개발되었을 때는 C++에 아직 템플릿이란 게 없었기 때문이다. 그리고 그 흔한 namespace조차 쓰지 않았다. 당연히 그때는 namespace가 없었기 때문.

MFC가 드디어 어느 정도 안정화를 이뤄 낸 것은 비주얼  C++ 4.2에서 도입된 MFC 4.2이다(MFC42.DLL). 비록 후속 버전인 비주얼 C++ 5와 6에서 개선과 기능 추가가 있었지만, 이것은 하위 호환성이 완벽하게 유지되는 변화이기 때문에 파일 이름이 동일했고, 이것이 MFC42.DLL이 윈도우 98 이래로 모든 윈도우 운영체제가 기본 내장하고 있는 표준 MFC DLL이 되었다.

오늘날 운영체제가 제공하는 MFC42.DLL은 이제 비주얼 C++ 6.0이 제공하던 클래식 MFC42.DLL과 하위 호환성만 유지되는 superset으로, 비주얼 C++과는 별개로 운영체제가 관리하는 DLL이다. 가령, 윈도우 7의 워드패드와 그림판은 명목상 MFC42.DLL을 사용하지만, 원래 VC6에는 없던 리본 인터페이스를 자기네 MFC42.DLL로부터 가져와서 사용하고 있다.

16비트에서 32비트로 넘어가면서 MFC는 일부 내부 자료구조가 바뀌었다. 특히 handle map은 스레드마다 서로 따로 돌아가기 때문에, 서로 다른 스레드끼리 핸들을 주고받을 때는 MFC 개체가 아닌 핸들을 직통으로 주고받아야 안전하다.

뭐, 이뿐만이 아니라 자체 구현으로 표시하던 toolbar와 status bar가 윈도우 95/NT 3.5부터는 common control이라고 운영체제에 정식으로 편입되었기 때문에, 그걸 그냥 끌어다 쓰는 걸로 내부 구현이 바뀌었다는 것도 첨언하겠다.

비주얼 C++ 6에서 닷넷으로 넘어가면서는 CString 같은 기초 자료형이 MFC가 아닌 ATL이라는 다른 라이브러리로 내부 관할이 바뀌고, 완전히 템플릿 기반으로 바뀌어서 한 코드로 ansi string과 wide string을 모두 다룰 수 있게 되었다. 그리고 DLL의 배포 방식이 변화를 겪기도 했다.

그 뒤 MFC는 2000년대에 들어와서는 이렇다 할 큰 변화가 없었고, 하루가 다르게 발전하는 C# 언어와 닷넷에 비해 MS가 네이티브 개발을 너무 홀대하는 게 아니냐는 우려의 목소리가 나올 정도였다. 특히 MS는 오피스 제품을 주축으로 독자적인 화려한 GUI(메뉴, 툴바 등)를 선보였고 오피스 2007부터는 리본 UI라는 완전히 새로운 물건까지 선보여 왔는데, 이를 모방하여 구현해 주는 MFC 기반 싸제 GUI 라이브러리가 제3자에 의해 미들웨어로 전문적으로 개발되어 판매될 정도가 되었다. 이름하여 GUI 툴킷.

과거 오피스 97/2000까지만 해도 프로그램 비주얼이 운영체제의 그것과 그렇게 큰 차이는 없었다. 그러나 오피스 XP부터 운영체제 기본 프로그램의 비주얼과 그런 오피스(?)급 프로그램의 비주얼은 이질감이 확 생겨 버렸다. 사실은 오피스 XP의 그 하얗고 깔끔한 2D같은 GUI가 윈도우 XP의 전반적인 GUI 디자인이 될 예정이었는데, 그 계획이 수틀리는 바람이 그 오피스 계열하고 운영체제의 알록달록 둥글둥글(?)한 디자인 계열은 따로 놀게 된 거라고 한다.

다음 하편에서는 이 GUI 툴킷과 관련된 MFC의 변천사 이야기를 계속하겠다.

Posted by 사무엘

2012/03/27 08:35 2012/03/27 08:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/660

델파이 (개발툴)

한 달쯤 전에 비주얼 베이직 리뷰를 쓴데 이어 오늘은 델파이와 해당 계열 RAD 툴의 리뷰를 좀 써 보겠다.
비주얼 베이직뿐만이 아니라 델파이와 C++ 빌더(C++ Builder)는 본인이 지금 같은 골수 비주얼 C++ 유저가 되기 전에, 도스에서 윈도우 프로그래밍으로 넘어가던 과도기 시절에 잠깐 써 본 개발툴이다. 고등학교 시절의 추억이 담겨 있다.

일단 파스칼이라는 언어 자체가 본인이 베이직에서 C/C++로 넘어가기 전에 과도기적으로 잠깐 공부했던 언어이다. 당시 정보 올림피아드 공부용으로 파스칼이 아주 깔끔하고 좋다는 말이 있기도 했고 말이다. 이 언어는 정말로 베이직과 C 사이의 과도기 역할을 하면서 본인의 프로그래밍 패러다임의 전환에 굉장한 도움을 주었다.

도스용 볼랜드 파스칼 역시 상당히 잘 만든 개발툴이었다. 그래서 본인은 이걸로 뭔가 이렇다할 프로그램을 개발해 보지 못한 게 좀 아쉽다. 개발툴의 본좌(?)이던 마이크로소프트와 볼랜드는 둘 모두 도스에서는 16비트의 한계를 벗어나질 못했으니 말이다. 그리고 지금 역시 <날개셋> 한글 입력기처럼 극도의 최적화를 추구해야 하는 프로그램은, 비주얼 C++만치 더 적격인 툴이 없는 것도 어쩔 수 없는 현실이다.

1990년대 초중반에 마이크로소프트가 '비주얼' 브랜드로 새로운 개발툴을 내놓은 것처럼 볼랜드는 오브젝트 파스칼 기반의 완전히 새로운 RAD 툴을 내놓았다. 그것이 바로 델파이. 게다가 1995년에 첫 출시된 1.0은 전무후무하게 16비트 윈도우용이었다.

델파이는 원래 AppBuilder라는 제품명이 붙을 예정이었고 Delphi는 코드명일 뿐이었다. 내 기억이 맞다면 이에 대해서 재미있는 일화가 전해진다.
잘 알다시피 IT계엔 그 이름도 유명한 Oracle이라는 데이터베이스 엔진(DBMS)가 있다. 이거 참 센스 있는 작명인게, DB에다가 SQL을 때려서 쿼리가 수행되는 것을 마치 신탁을 내리는 것에다 비유한 것이다. “수천만 개의 레코드 중에서 요것과 연계하여 이런 조건을 만족하는 놈을 눈앞에 0.1초 안에 대령하라.” 검색 엔진에다 심마니라는 이름을 붙인 것과 비슷한 맥락의 작명이라 하겠다.

그런데 신탁이 내려지는 곳이 어디던가? 신전이다. 그리고 고대 그리스에는 델파이라는 도시에 아폴로 신전이 있었다.
델파이는 DB와 연동하는 업무용 프로그램을 파스칼 언어를 기반으로 빠르고 편리하게 개발해 내라고 만들어진 개발툴이다. 그래서 DB 쿼리라는 신탁이 내려지는 장소에다 빗대어 델파이라는 코드명이 정해졌고, 이게 곧 제품명이 되었다. (뭐, 굳이 DB를 안 쓰더라도 각종 유틸리티나 에디터, 툴을 만드는 용도로도 좋지만 말이다.)

이런 이유로 인해, 델파이는 지금까지도 신전이나 집 비슷한 모양을 한 아이콘을 갖고 있다. 델파이의 C++ 버전이고 델파이보다는 훨씬 덜 유명한 C++ Builder는 집+크레인처럼 생긴 건축 기계 모양 아이콘이다. C++ 빌더는 다른 건 델파이와 비슷한데 역시 C++의 특성상 빌드 속도는 훨씬 더 느리며, RAD 툴의 용도에 맞게 C++ 문법을 자기 식대로 확장한 게 좀 있다. 또한 C++답게 경쟁사의 MFC 라이브러리도 내장하고는 있다.

그런 곳에서는 C++의 위상이 좀 므흣한 게, 닷넷으로 치면 마치 C++ managed extension 같은 존재이다. 닷넷에서는 아예 확실하게 C#을 쓰고 필요한 곳에나 unsafe 코드를 가끔씩 집어넣고 말지, 네이티브 기계어 개발이 아니라면야 C++이 얼마나 메리트가 있겠나 싶다. C/C++을 쓸 정도이면 아예 Win32 API만을 이용한 하드코어 저수준 개발을 하지, 애초에 RAD용으로 만들어진 게 아닌 언어에다가 그 정도로 추상화 계층을 거친 RAD 껍데기를 거추장스럽게 씌울 필요가 있겠나 하는 생각이다.

볼랜드에서는 자기네 RAD 툴에다가도 닷넷 기술을 연동하여 C# Builder 같은 툴을 만들기도 했지만 이건 얼마 못 가 접었다. 다들 비주얼 C#을 쓰지 굳이 볼랜드 툴을 쓰지 않았기 때문. 볼랜드는 그런 자신의 RAD 영역을 더욱 발전시켜서 마치 qt 같은 크로스 플랫폼 개발 프레임워크를 표방하며 리눅스용으로 카일릭스(Kylix)도 내놓고, 지금은 맥 OS X 범용 개발 환경도 내놓았는데, 아이디어는 분명 좋다만 결과는 과연 어떨까 궁금하다. 카일릭스는 수 년 전에 망했고 개발이 중단됐다.

하긴, 말이 나왔으니 말인데 얘들은 개발사의 명칭이나 주체가 여러 번 바뀌었다(개명· 인수 합병). 볼랜드이다가 한때는 Inprise, Codegear를 거쳐 지금은 Embarcadero임.

이런 저런 사정이 많았으나 델파이는 결국 오늘날까지도 그냥 윈도우 플랫폼 한정으로 강세인 것으로 보인다. 나름 네이티브 코드(오옷!)를 가히 C++로는 엄두를 못 낼 전광석화의 속도로 생성하는 RAD 툴이니, 생산성은 확실히 우위이다. 프레임웍에 속하는 코드가 단일 exe에 모조리 static 링크되어 들어가기 때문에, Hello world 급의 프로그램도 Release 빌드의 exe는 1MB 이상은 먹고 들어간다.

비주얼 C++ 2008 이상부터는 MFC를 static link해도 그 정도는 먹고 시작한다. 과거의 6.0 시절에는 MFC의 static link 오버헤드 크기가 200~300KB대였는데, 재미있게도 그 당시의 델파이 2~3도 exe의 기본 크기가 그 정도였으니 옛날이나 지금이나 오버헤드가 서로 비슷하다.

이런 이유로 인해, 델파이로 개발된 프로그램은 실행 파일을 실행 파일 압축기로 압축한 채 배포되는 경우가 종종 있다. 하지만 압축된 실행 파일은 코드 실행 영역이 동적으로 생성되고 고쳐지기 때문에, 동일 EXE가 중복 실행되었을 때 코드 영역이 동일한 물리 메모리를 공유하여 메모리를 절약하는 효과를 못 보지 싶다. 실행 파일 압축기가 집어넣어 준 압축 해제 stub이 그런 걸 똑똑하게 감지하여 처리하지 않는다면 말이다. 뭐, 요즘은 어차피 메모리도 차고 넘치는 시대이긴 하지만...;;

내 기억이 맞다면, C++ Builder는 델파이와는 달리 수 MB짜리 vcl.dll (Visual Component Library) 런타임이 필요한 작은 exe를 생성했었지 싶다. 즉, 정적 링크가 아니라 동적 링크 방식.

그런데 얘들의 프레임웍 라이브러리는 덩치만 큰 게 아니라 윈도우 API를 나름 체계적으로 잘 커버하고 있다. MFC는 윈도우 API에다 아주 최소한의 껍데기만 씌운 것에 가까운 반면, 볼랜드의 라이브러리는 운영체제 API에는 존재하지 않는 여러 추상적인 계층을 더 만들고, 심지어 같은 에디트 컨트롤도 single line (TEdit)과 multi line (TMemo) 버전을 따로 만들었다. MFC는 그냥 CEdit 하나로 끝인데 말이다. 내부 구현이 옵션만 다르게 지정된 동일한 에디트 컨트롤이니까 말이다.

라디오 버튼이나 체크 버튼도 under the hood는 그냥 버튼 컨트롤일 뿐이기 때문에 MFC는 CButton 하나로 끝이다. 그러나 볼랜드의 라이브러리는 응당 TRadioButton과 TCheckBox로 클래스가 따로 나뉘어 있다.
볼랜드의 프레임워크는 DC고 GDI 객체고 나발이고 생각할 것 없이 자기네가 마련한 TCanvas라는 개체를 통해 마음대로 색깔을 바꾸고 픽셀 단위 그래픽 접근이 가능한 반면, MFC에서는 그런 자비를 찾아볼 수 없다. 그런 추상화 계층을 마련하는 오버헤드가 exe의 실행 파일 크기 내지 런타임 DLL로 나타난다고 생각하면 됨.

이런 전통이 사실 볼랜드의 옛 C++ 라이브러리인 OWL (Object Windows Library)부터 어느 정도 전해져 오고 있었다. 델파이가 나오기 전, 볼랜드 C++/파스칼이 윈도우용으로 있던 시절 얘기이다. OWL이 좀 더 객체 지향 철학을 살려서 더 잘 만들어진 라이브러리이긴 했으나, 언제부턴가 IE가 넷스케이프를 누르듯이 MFC가 OWL을 떡실신시켜 버렸다.

세월이 세월이다 보니 델파이도 도움말 레퍼런스는 MS 비주얼 스튜디오의 Document Explorer를 쓰고 있어서 뜻밖이라는 생각이 들었다. 하긴, 옛날 버전은 아예 WinHelp를 쓰고 있었는데, 자기네만의 도움말 시스템을 새로 만드는 건 너무 뻘짓이고 그냥 chm을 쓰기엔 레퍼런스의 분량이 너무 방대한데, 저렇게 하는 게 나은 선택이다.

델파이의 근간 언어인 파스칼은 내부적으로 문자열을 포함하는 방식이 원래 C/C++과는 다르다. 그러나 운영체제의 각종 API들이 오로지 C/C++ 스타일의 null-terminated 문자열만을 취급하기 때문에 델파이 프로그래머도 C/C++ 스타일 문자열이라는 개념을 몰라서는 안 된다. 사실 파스칼과 C/C++은 함수 호출 규약조차도 달라서 과거에는 C/C++에서도 함수 선언할 때 STDCALL뿐만이 아니라 PASCAL이라는 속성이 있을 정도였다.

파스칼에도 포인터가 있긴 하다. 하지만 C/C++만치 배열과 포인터를 아무 구분 없이 남발할 수 있는 건 아니며 쓰임이 제한적이다. a[2]뿐만이 아니라 2[a]까지 가능한 건 가히 C/C++의 변태적인 특성이다만, 파스칼은 등장 초기에는 동적 배열이라는 개념 자체가 아예 없었다고 한다.
타입 선언에서 포인터를 의미하고 실제 수식에서는 포인터가 가리키는 값을 얻어오는 연산자가 C/C++은 *인데 파스칼은 ^이다.
그리고 이미 있는 변수의 주소를 얻어 오는 address-of 연산자는 C/C++은 &이고, 파스칼은 @이다.

델파이로 개발된 프로그램은 윈도우 비스타/7의 Aero 환경에서 창을 최소화해 보면 창이 작업 표시줄 쪽으로 미끄러지듯 fade out이 되지 않고 그냥 혼자 싹 없어지곤 했다. 나타나는 비주얼이 살짝 다르다. 델파이로 빌드된 다른 프로그램들을(특히 구버전) 살펴보면 차이를 알 수 있다.

그랬는데 최신 2011년도 델파이 XE2로 프로그램을 하나 빌드해 보니까 드디어 여타 프로그램처럼 제대로 최소화된다. 개선이 된 듯하다.
델파이가 유니코드와 64비트를 제대로 지원하기 시작한 것도 생각보다 최근이라고 들었다만.. 앞으로 이 툴이 어디까지 발전하고 MS의 비주얼 툴과는 다른 독자적인 지위를 유지할 수 있을지가 지켜보는 건 흥미로운 일일 것이다.

* 2014년 7월 1일 추가함.
델파이 1.0은 특정 업종 종사자들만 사용하는 딱딱한 개발툴인 주제에 무슨 게임을 방불케 하는 화려한 설치 화면을 자랑했다.

사용자 삽입 이미지

설치 프로그램이 full screen 모양으로 실행되는 게 유행이던 시절의 즐거운 추억이다. 본인도 중학생이던 시절 저 화면을 직접 본 적이 있다. 정말 개발툴 역사상 전무후무한 디자인이 아닐까 싶다.

속도계는 어떤 축적된 분량이 아니라 단위 시간당 변화량 개념이기 때문에,
굳이 이런 프로그램에 넣더라도 차라리 지금 파일의 전송 속도를 나타내는 용도가 더 적절할 것 같다만..;;
어쨌든 저 계기판에서 속도계가 전체 설치 진행 상황을 나타낸다.

굉장한 창의력과 잉여력이 아닐 수 없다. 그때는 MS Office 9x 프로그램에도 간단한 핀볼이나 3D 레이싱 게임이 이스터 에그로 들어가 있었을 정도이니 뭐...
단, 델파이의 경우 설치 중에 저 배경에서 차가 실제로 주행하여 배경이 입체적으로 스크롤된다거나 하지는 않는다. ^^ 그건 일말의 아쉬운 점이다.

Posted by 사무엘

2012/02/27 19:10 2012/02/27 19:10
, , ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/647

1.
겨울방학도 이렇게 끝이 보인다.
본인이 이번 방학 때 이뤄낸 가장 뜻 깊은 성과를 둘 꼽자면 하나는 <날개셋> 한글 입력기 6.5이고, 다른 하나는 HFT(아래아한글 전용 글꼴) 해킹 성공이다.

사용자 삽입 이미지

저 글꼴들을 MS 오피스 제품에서도 쓰고 PDF도 자유롭게 만들고, 무엇보다도 화면에 anti-alias가 된 부드러운 모습으로 보니 너무 좋다.. 근성의 reverse engineering 오덕질을 통해서 이뤄 낸 성과. ㅋㅋ 새로운 글꼴로 아무 글이나 마구마구 써 보고 싶다.

또한, 날개셋 6.5 버전은 아직까지도 프로그램을 크게 고친 부분이 없을 정도로 역대 최고로 손꼽히는 안정성과 완성도로 잘 만들어졌다. 대단히 만족스럽다. 그래서 당분간 안심하고 완전히 새로운 기능 연구와 논문 준비 등에 전념할 수 있을 것 같다.

2.
윈도우 7은 콘솔(명령창)에서 세벌식을 쓰면 '다다.' 이렇게 한글이 덧나는 버그가 있다. 왜 SP1에서도 안 고쳐진 걸까? 예전에도 언급한 적이 있지만, 이런 건 두고두고 디스를 좀 해 줘야 된다.
윈도우 운영체제는 NT 계열도 꼭 이런 이상한 버그가 역사적으로 하나씩 있었다.

과거 2000은 256색으로 들어갔다가 돌아오면 군청색 제목 표시줄의 색깔이 옅어지는 버그를 유일하게 갖고 있어서 SP4에서까지 안 고쳐졌고,
XP는 테마를 저장했다가 불러오면 Luna 모드에서도 메뉴가 클래식 모드처럼 표시되어 색깔이 이상해지는 버그가 있는데 역시 SP3에서까지 안 고쳐지고 저렇게 끝났다.

이런 이유로 인해 본인은 한글 IME 개발과 관련하여 까탈스럽고 안 좋은 추억 때문에 남들이 7 좋아하는 것만치 7을 좋아하지는 않으며, 남들이 비스타 싫어하는 것만치 비스타를 싫어하지도 않는다. -_-;; 뭐, 비스타도 희한한 버그 의심 증상이 하나 있긴 했으나, SP1에서 곧바로 고쳐짐.

3.
<날개셋> 편집기는 txt 확장자를 자기 프로그램으로 연결한다거나 하지는 않는다.
그렇기 때문에 이렇게만 놔 둬서는 윈도우 7의 jump list를 활용하지 못한다. (윈7 사용자 중에 jump list가 뭔지 모르는 분은 없으리라 생각되지만, 어쨌든 모른다면 검색 요망)

탐색기에서 txt 파일을 우클릭하여 '연결 프로그램 선택 → 찾아보기' 등을 골라서 <날개셋> 편집기를 한 번이라도 지정한 뒤(꼭, 기본 연결을 시켜 놓을 필요는 없고 이렇게만이라도), 나중에 <날개셋> 편집기의 열기 대화상자로 txt 파일을 열고 나면 그건 앞으로 jump list 에 등재되게 된다.

jump list를 좀 더 창의적으로 활용하면, 편집기는 당장 저런 기본 용도만으로도 충분할 것이고(최근 파일 열기),
변환기는 클립보드 변환 같은 자주 사용할 만한 task를 등록해 놓을 수 있겠으며,
입력 패드는 자주 쓰는 보조 입력 도구를 실행과 동시에 바로 꺼내 놓게 할 수 있겠는데 더 자세한 활용법에 대해서는 좀 더 시간을 두고 고민해 봐야겠다.

4.
얼마 전엔 드디어 <날개셋> 한글 입력기 프로젝트를 비주얼 C++ 2010용으로 정식으로 포팅해서 빌드해 봤다. 특이사항으로는,

- 사소한 컴파일 에러가 있었으나, 더 깔끔하고 분명한 코드를 만드는 데 도움이 되는 에러였으며 쉽게 잡았다.
- VS 2010의 빌드 시스템은 $(TargetPath) 변수의 값을 예전과는 다른 방식으로 부여하는 듯하다. 그래서 이걸 조정하는 노가다를 매 프로젝트들마다 좀 해야 했다.

이것 외엔 딱히 트러블이 없었으니 무리 없이 잘 갈아탔다.

동일한 옵션으로 빌드했지만 x86 바이너리(32비트)들은 VS 2008과 비교했을 때 크기가 살짝 더 커졌고, x64 바이너리(64비트)들은 살짝 더 줄어들었다.
같은 코드를 빌드했을 때 바이너리 크기가 조금씩 더 커지는 건, VC6 이래로 개발툴이 업데이트되면서 비교적 일관되게 관찰되는 추세였다. 최적화가 인라이닝 등 코드 크기를 더 키우는 쪽으로 행해져서 그런 것 같다.

비주얼 C++ 2010은 C/C++ 언어도 빌드 중에 'Linking...'이라는 말이 안 뜨고 generating code...에 링킹이 포함되는 듯하다.
똑똑한 인텔리센스는 부러운 점이긴 하다만, 너무 커진 덩치, 이질감이 생긴 GUI와 도움말 시스템 때문에 2010은 개인적으로 언제쯤 도입하게 될지 모르겠다. 다만, 리소스 에디터가 드디어 윈도우 비스타의 PNG 내장 아이콘(256*256)까지 제대로 표시해 주는 점은 마음에 든다.

5.
내 경험상 윈7은 USB 메모리(스틱 or 외장 하드) 매체의 제거를 예전 OS에 비해 더 관대하게, 더 빨리 허용해 주는 것 같다. 해당 드라이브를 사용하는 프로그램들을 다 껐는데도 '사용 중이기 때문에 제거 못 함' 꼬장 때문에 할 수 없이 아예 OS를 로그오프하거나 아니면 그냥 강제로 매체를 제거해 버린 일이 거의 발생하지 않았다.

그리고 다른 얘기이다만, 윈도우 7은 Taskbar에 있는 각종 프로그램들 아이콘과 시스템 트레이의 아이콘을 드래그하여 마음대로 순서를 바꿀 수 있는 게 무척 인상적이다.
7에서 새로 바뀐 작업 표시줄은, 실행 중인 프로그램과(동일 프로그램이 중복 실행된 것 포함) 그렇지 않은 프로그램의 구분이 잘 되아 보이는 걸 개인적으론 안 좋게 생각했었다. 그러나 한동안 써 보니까 이게 그럭저럭 나쁘지 않은 디자인이라는 생각이 든다.

무엇보다도, 창을 몇 개씩 띄워 놔도 많이 띄웠다는 느낌이 심리적으로 안 드는 게 인상적임.
옛날에 윈9x의 전통적인 시작 메뉴 시절엔, 컴을 몇 년 쓰면서 수십 종류의 프로그램들을 설치하고 나니까 '프로그램' 메뉴 옆으로 프로그램 리스트가 두 칼럼 이상씩 차지하는 크고 아름다운 면적으로 주렁주렁 달렸던 거 기억하는가?

또한 인터넷 서핑하다가 브라우저 창이 열몇 개씩 넘어가니까 작업 표시줄 모습이 가히 가관으로 바뀌던 것도 기억하시는지? 윈도우 7은 복잡도를 제어하는 디자인에 무척 신경을 썼다..

6. 윈도우 비스타와 7 모두, 로그인 화면에서 암호를 입력하고 나면, 암호가 맞든 틀리든 일단 Welcome부터 출력하면서 설레발을 치다가 그 뒤에 암호가 틀렸으면 사용자 진입을 거부한다. “안 돼! / 돼!”도 아니고 츤데레도 아니고 이건 도대체 무슨 디자인일까?? -_-;;
암호가 맞을 때만 Welcome을 출력하게 개선되면 좋겠다.

7.
윈도우 9x는 프로그램을 조심해서 짜는 데에 도움을 준다.
NT 계열에서는 해제했던 메모리를 중복 해제하거나, 자원을 반납· 해제하는 걸 깜빡하는 식으로 대충 대충 짜도 당장 티가 안 나며 그냥 넘어간다. 그러나 9x에서 그랬다간 얼마 못 가 시스템 자원이 바닥난다거나 바로 뻗어 버리기 때문에, 이런 차이 덕분에 프로그램을 윈도우 9x에서 테스트하다가 버그를 발견하여 구조적인 문제를 해결한 경우가 지금까지 종종 있다.

아마 <날개셋> 한글 입력기도 한 2~3년 동안 윈9x에서 테스트를 안 한 채 개발을 계속하다가 버전이 1.0쯤 올라간 뒤에 다시 윈9x용으로 테스트하면, 여기저기서 원인을 알 수 없는 버그가 자꾸 튀어나와서 단순히 유니코드 API layer를 쓰는 것만으로는 윈9x를 결코 다시 지원할 수 없는 수준에 이를 것이다.
지금 <날개셋> 한글 입력기 소스가, 비록 같은 C++언어이지만 비주얼 C++ 6.0으로는 도저히 개발을 계속할 수 없는 이질적인 단계에 도달한 것처럼 말이다(각종 문법 차이 때문).

Posted by 사무엘

2012/02/23 08:33 2012/02/23 08:33
, , , ,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/645

윈도우 운영체제에는 잘 알다시피 DLL이라는 게 있어서 한 프로세스를 구성하는 코드들을 여러 모듈로 분할할 수 있고, 반대로 동일한 코드를 여러 프로세스가 동시에 효율적으로 공유할 수 있다. 유닉스 계열의 운영체제에는 이와 비슷한 개념으로 shared library (*.so)라는 게 있다.

윈도우 DLL은 주소 공간이 해당 DLL을 로딩한 프로세스(EXE)에 완전히 종속된다. 그렇기 때문에 DLL이 사용하는 코드는 공유될지언정, 그 DLL이 선언하는 전역변수 같은 건 EXE마다 제각각이며, 심지어 동일 EXE를 여러 번 실행하더라도 제각각이다. 이것은 유닉스의 shared library와 다른 점이다. 윈도우에서 진짜 여러 프로세스들이 공유할 수 있는 메모리를 만들려면 내부적으로 공유되는 메모리 섹션을 별도로 생성해 놔야 한다.

이런 차이로 인해 특별히 조심해야 할 점이 있다. 한 EXE 안에서 3개의 DLL이 돌아가고 있고, 이들은 모두 동일한 버전의 비주얼 C++로 개발되어 동일한 CRT 라이브러리를 사용한다고 치자. 만약 이들이 모두 CRT를 DLL로 링크하여 동일한 CRT 라이브러리의 코드와 데이터를 공유한다면, 어느 모듈에서 malloc/new한 메모리를 다른 모듈에서 곧바로 free/delete해도 된다.

그러나 이들이 제각각 CRT를 static link했다면 그럴 수 없다. 한 모듈에서 할당한 메모리는 반드시 동일한 모듈에서만 해제해야 한다. 비록 메모리를 할당하고 해제하는 코드는 실질적으로 동일하지만 해당 코드가 동작하는 context는 모듈들이 모두 서로 다르기 때문이다. 모듈간에 메모리 할당과 해제를 자유롭게 하려면 각 모듈들은 자신만의 메모리 할당/해제 함수를 외부에다 별도로 제공해 줘야 한다.

DLL을 만드는 일은 64비트 운영체제가 등장하면서 다소 까다로워졌다. 32비트와 64비트 사이에는 DLL의 교차 로딩이 되지 않기 때문이다. 즉, 32비트 모듈(EXE/DLL)은 64비트 DLL을 읽을 수 없으며, 반대로 64비트 모듈은 32비트 DLL을 읽을 수 없다. 다시 말해, x64 운영체제에서도 x86 EXE를 아무 차이 없이 실행은 할 수 있지만, 그래도 64비트 EXE가 32비트 DLL을 내부적으로 읽을 수는 없으므로 착오 없기 바란다.

한 주소 공간은 전부 32비트 아니면 전부 64비트뿐이지, 두 종류의 코드가 섞여 있을 수가 없어졌다. 옛날과는 달리 지저분한 썽킹 계층 같은 게 없다. 동일 코드를 32비트와 64비트용으로 제각기 빌드해서 다같이 내놓아야 한다.
그러니 태생적으로 반드시 네이티브 코드 DLL을 만들어야 하는 컴포넌트/미들웨어/드라이버 분야라든가, 훅킹 내지 운영체제의 shell extension을 만드는 쪽은 다른 어떤 분야보다도 진작부터 64비트 프로그래밍이 필요했다. 사실은 IME 쪽도 예외가 아니다.

그런데 문제가 있다. 지금까지 DLL은 코드를 담는 용도로만 쓰여 온 게 아니라는 점이다. 잘 알다시피 윈도우 운영체제는 실행 파일의 포맷 차원에서 리소스라 하여 나름 계층을 갖춘 custom 데이터를 간편하게 불러오는 기능이 있다. 일일이 메모리 할당을 할 필요가 없이, 운영체제가 알아서 메모리 주소를 잡아서 로딩해 주고, API 함수 호출 한 번에 데이터를 곧장 찾아 주기까지 하니, 상당히 편리하다. 그래서 데이터 리소스만 갖춘 DLL도 엄청 많이 쓰였다.

특히 다국어 지원을 위한 외국어 리소스를 집어넣는 데 DLL보다 더 좋은 수단은 지금까지 별로 없었다. 운영체제의 대화상자 내지 string table 같은 주요 리소스 파일의 포맷은 32비트나 64비트나 바뀐 게 없다. 호환성 차원에서 일부러 동일하게 유지시킨 듯하다. 비주얼 스튜디오 200x의 MSDN(Document Explorer)이 사용하는 *.hxs 파일도 리소스 전용 DLL이다.

그런데 DLL은 태생적으로 컴퓨터 기계 종류에 지극히 종속적인 코드를 담는 게 주 목적인 파일 포맷이다. 그렇다면 기계 종류에 관계없이 동일한 데이터를 담는 DLL도 기계별로 일일이 다 따로 만들어야 할까?
그렇지는 않다. 데이터밖에 들어있지 않은 리소스 전용 DLL을 위해서 운영체제는 다음과 같은 배려를 하고 있다.

먼저, DLL을 읽을 때 흔히 사용하는 LoadLibrary 대신, LoadLibraryEx 함수는 LOAD_LIBRARY_AS_IMAGE_RESOURCE 같은 플래그를 제공하여 DLL의 코드 부분을 전혀 감안하지 않고 데이터 부분만 읽게 할 수 있다. 이렇게 하면 해당 DLL은 DllMain 함수 자체가 실행되지 않으며, 자신과 호환되지 않는 기계를 타겟으로 만들어진 DLL도 읽을 수 있다. 물론, FindResource 같은 함수로 리소스 추출만 가능할 뿐, GetProcAddress 같은 기능을 사용할 수는 없다.

다음으로, DLL 자신이 리소스 전용 DLL일 뿐이라고 명시해 줄 수 있다. 비주얼 C++의 DLL 프로젝트에서 링커 옵션을 보면 /NOENTRY가 있다. 이 옵션이 지정되면 그 DLL에는 아무 코드도 삽입되지 않으며, 진입점인 DllMain 함수 자체가 없는 리소스 전용 DLL임이 인증된다. 이런 DLL은 외부에서 그냥 대놓고 LoadLibrary로만 호출해도 기계 종류에 관계 없이 읽을 수 있다.

윈도우는 공유 라이브러리를 다루는 개념이 유닉스 계열과 차이가 있을 뿐만 아니라 실행 파일을 로딩하는 방식에도 개념적인 차이가 있다. 윈도우는 position-dependent, 즉, 주소 종속적인 방식이다. 윈도우의 EXE와 DLL에는 preferred address라는 게 있어서, 이 메모리 주소에 딱 로딩이 되면 아주 성능이 좋지만, 그 주소에 로딩이 못 되면 재배치 페널티가 따르는 방식을 사용한다. 재배치 작업을 어떻게 하면 되는지에 대한 재배치 정보가 reloc이라는 섹션에 있다.

EXE야 Win32s 같은 과거의 열악한 환경이 아닌 이상, 자신만의 고유한 주소 공간이 있기 때문에 언제나 preferred address에 로딩된다는 보장이 있다. 그에 반해 남의 주소 공간에 달라붙는 형태인 DLL은 그렇지 못하기 때문에 일반적으로 반드시 reloc 섹션이 필요하다.
다만, 이런 재배치 작업도 코드가 없는 리소스 전용 DLL에는 전혀 해당사항이 없다. 리소스 내부에 DLL의 메모리 주소에 종속적인 숫자 데이터 같은 게 있을 리가 없기 때문이다.

그러니 이론적으로 리소스 전용 DLL은 reloc 정보를 생략해 버려도 괜찮지만, 그냥 대놓고 생까-_- 버리는 것도 곤란하다. 윈도우 2000 미만의 옛날 운영체제의 경우 DLL을 preferred base에다 로딩을 못 하는데 재배치 정보마저 없다면, 원래 재배치를 할 게 없는 리소스 전용 DLL임에도 불구하고 그냥 일방적으로 로딩을 거부해 버리게 된다.

재배치를 안 해도 괜찮은 DLL이라는 별도의 플래그는 윈도우 2000 이상에서부터 도입되었다. 물론, 애당초 기계어 코드가 들어있지 않은 DLL의 reloc 섹션에 의미 있는 재배치 정보 자체가 있을 리가 없다. 그냥 껍데기뿐인 잉여인 것이다.

이렇듯, DLL은 원래 코드를 공유하려고 만들어졌지만 기계와는 무관한 리소스나 데이터를 공유하는 container 역할도 결코 무시할 수 없는 위치에 있다. 심지어 트루타입(TTF) 글꼴이 도입되기 전에 윈도우에서 쓰이던 비트맵/벡터 글꼴인 FON 파일은 16비트 형태의 리소스 전용 DLL로, 오늘날의 64비트 윈도우에서도 그 잔재가 남아 있다!

그래서 운영체제가 리소스 전용 DLL에 대해서는 예외적으로 기계를 가리지 않고 읽을 수 있고, 또 그런 DLL에는 불필요한 정보를 합법적으로 생략도 할 수 있게 별도의 배려를 해 왔음을 우리는 윈도우 API의 변천사를 통해 알 수 있다.
그러고 보니, 32/64비트 응용 프로그램이 각각 32/64비트에 해당하는 윈도우 시스템 디렉터리나 각종 프로그램 디렉터리를 얻어 오고 접근하는 법도 꽤 복잡해져 있는데, 이건 다음 기회에 다루도록 하겠다.

Posted by 사무엘

2012/02/19 08:29 2012/02/19 08:29
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/643

살다 보니 C#이나 파이썬도 아니고 비주얼 베이직으로 작성된 코드를 C++로 포팅해야 할 일이 있었다. C/C++로 갈아탄 뒤로는 베이직 코드는 다시는 볼 일이 없을 줄 알았는데 이거 정말 몇 년 만이냐.

들여다봐야 하는 코드는 닷넷도 아니고 비주얼 베이직 6으로 만들어진 코드였다. 하지만 GUI가 아니라 계산 알고리즘을 포팅하는 것이기 때문에 포팅이 크게 어려운 건 없었다. VB6에서 닷넷으로 넘어가면서 완전히 뒤집어엎어진 건 API 체계이지, 언어 자체가 그렇게 많이 바뀐 건 우려한 것만치 많지 않아 다행이었다. 자바와 자바스크립트의 관계에 필적하는 이질감은 아닌 것 같다.

언어가 바뀐 것은,
- 첫째, statement이던 것이 C 언어의 영향을 받아 다 일관된 함수 호출 형태로 바뀜. 그래서 매개변수 전체를 괄호로 싸야 됨. (파이썬도 3.0에서는 print가 statement에서 함수로 바뀜)

- 둘째, 타입이 예전보다 더 엄격해지고, 모든 변수는 반드시 사용 전에 선언을 해 줘야 함. 베이직은 원래 그런 걸 안 하는 언어이다가 하는 걸로 바뀌었다 보니, 변수를 선언하는 키워드가 Var이 아니라 Dim...이다. 원래는 배열을 선언할 때만 쓰는 키워드였지.
이런 추세를 정면으로 역행하는 GWBASIC의 잔재인 DefINT A-Z 같은 명령문은 당연히 퇴출이다.

- 셋째, 그리고 객체지향 패러다임에 맞춘 API의 전면 재구성이다. 예전엔 그냥 global 단위로 곧바로 호출하던 함수도 다 분야가 나뉘어서 클래스나 namespace에 소속된 메소드로 바뀌었다. 그래서 수학 함수도 바로 Sqrt라고 하면 안 되고 Math.Sqrt라고 써 줘야 하며, Math를 자주 쓴다면 Using 선언을 한 뒤에 생략해야 한다. 하긴, 비베에는 예전부터 With 키워드는 있긴 했다만.

이 정도.
요즘 언어들은 C/C++ 영향을 받아서 다들 대소문자 구분을 하는 게 유행이기 때문에, 혹시 비주얼 베이직도 그렇게 바뀌지 않았으려나 생각했다만...
의외로 명칭에 대소문자 구분을 안 하는 건 VB6이나 닷넷이나 마찬가지이다.

베이직은 원래 좀 가볍고 동적인 언어였는데, MS의 닷넷 입맛대로 대수술을 거치다 보니 그냥 C#의 표현력에 필적하는 전형적인 절차형 언어가 된 것 같은 느낌이 든다. 예전의 베이직 같은 느낌은 파이썬이 더 잘 간직하고 있는 듯.

배열 첨자도 ()로 싸고, 함수 호출 인자도 ()로 싸는 건 베이직의 특징이다. 언뜻 보기에 굉장히 혼동될 것 같은데 C++처럼 [] () 따로 연산자 오버로딩이라도 해야 하는 게 아니라면 의외로 둘이 문법 차원에서 혼동될 일은 없다. 참고로 본인은 ::와 .의 구분이 없는 객체지향 언어들에 대해서도 의아해한 적이 있었는데 이 구분 역시, 포인터만 없다면 거의 필요하지 않다.

그러고 보니 베이직은 대입도 =, 동등 비교도 =이다. A=B=1이라고 하면 C언어 식으로 치자면 A=B==1처럼 해석된다. 원래 베이직의 대입문은 Let A=1 처럼 써 줘야 맞는데 Let이 C언어의 auto만큼이나 캐잉여로 전락하는 바람에 지금 같은 꼴이 된 것이다. 그러고 보니 Let을 Dim처럼 변수 선언 키워드... 아니 C++0x의 auto처럼 쓰는 것도 괜찮을 것 같다?

Dim A as Double
Dim I as Integer

뿐만 아니라

Let A = 0.52 '자동으로 실수 확정
Let I = 5    ' 자동으로 정수 확정

이렇게도 되게 말이다. 타입이 이랬다저랬다 바뀌는 Variant가 아님. 기발하지 않은지? ㄲㄲ

베이직처럼 구문 분석이 쉬운 언어는 IDE의 인텔리센스나 코드 자동 완성 같은 기능이 C++의 그것과는 비교할 수 없이 안드로메다급으로 훨씬 더 빠르고 똑똑하고, 돌아가는 게 손에 착착 달라붙는다. 도스 시절의 퀵베이직이 이미 인텔리센스만 없을 뿐이지 그런 꿈의 프로그램 개발 환경을 어느 정도 제공하고 있었다. 빌드 속도는 두말 할 나위도 없음.

그러나 C++ 코드는 실시간으로 코드 변경 사항을 IDE가 따라잡으려면, 비주얼 스튜디오든 Source Insight든, 어쨌든 background에서 소스를 다 까 보는 작업을 하지 않으면 안 된다. 그래서 어떻게든 처리 속도를 올리려고 덕지덕지 남기는 부가 정보 데이터가 많다. 함수 이름을 바꾼 게 C/C++은 복잡한 절차를 거쳐 최소한 수 초 뒤에 IDE의 ClassView에 반영되는 반면, 베이직은 ‘즉시’이다.

이런 생산성과, C++ 특유의 졸라 가볍고 효율적인 네이티브 코드라는 두 마리 토끼를 모두 잡은 프로그래밍 언어 + 개발 환경은 정녕 없는 것일까.
하긴, 윈도우 환경에서 베이직 언어로 네이티브 코드를 생성하는 컴파일러는 MS 제품 중에는 없고 파워베이직이라는 브랜드가 있다. 하지만 인지도가 안습한 수준.

Posted by 사무엘

2012/01/26 08:45 2012/01/26 08:45
,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/632

비주얼 C++ 관련 잡설

1. 비주얼 C++ 한글판

마이크로소프트에서 한글화한 프로그램의 UI에서 이런 저런 오역이 발견되는 건 어제 오늘 일이 아니다. 뭐, “안녕하신가, 힘세고 강한 아침!” 수준의 막장 발번역-_-은 아니지만, 이런 오역이 간간히 발견되는 주된 이유는, 번역자가 해당 소프트웨어가 다루는 분야의 용어를 잘 알지 못해서일 것이다. 그리고 어떤 문장이나 단어가 실제로 프로그램의 어느 부분에서 등장하는지를 모르는 채, 그냥 번역 리스트만 쭉 보면서 아무 문맥 정보가 없이 기계적으로 번역만 했기 때문일 것이다.

마이크로소프트가 개발한 소프트웨어 개발툴 중 비주얼 베이직은 5던가 6 시절부터 이미 한글화가 되었다. 그 반면, 가장 어렵고 하드코어한 개발툴인 비주얼 C++ 6은 한글화되지 않았으며 닷넷에서부터 통합 IDE가 제공되는 과정에서 드디어 한글화가 됐다. 그러나 베테랑 개발자 중에 한글판 IDE를 선호하는 사람은 거의 없으며, 이 점에서는 본인도 마찬가지이다.

옛날에 유니코드라는 것도 없고 PC의 환경이 극도로 열악하던 시절에는 한글판이 대놓고 영문판보다 성능이 열등했다. 텍스트 모드에서 한글 바이오스를 띄웠을 때와 띄우지 않았을 때의 성능 차이는 말할 나위도 없고, 도스 시절에 한글 QuickBasic은 성능은 둘째치고라도 그야말로 퀵라이브러리(qlb) 파일 포맷이 영문판과 호환조차 되지 않던 쓰레기-_-였다.

영문 윈도우 95는 4MB 램에서 그럭저럭 돌리는 게 가능했던 반면, 각종 무거운 한글· 한자 글꼴을 얹어야 했던 한글 윈도우 95는 최하 6~8MB 램이 필요했다. 그것도 어지간한 PC의 메모리가 4~8MB 사이이던 시절에!
난 아직도 기억이 생생한 게, 펜티엄급 노트북에서 IE4를 띄웠는데 빽빽한 영문으로 된 사이트는 비교적 매끄럽게 스크롤된 반면, 빽빽한 한글이 적힌 사이트(그냥 굴림체 비트맵 글꼴 크기)는 스크롤이 상당히 굼떴었다.

그도 그럴 것이 윈도우 세계에서는 '한글'이 그것만 특별 취급해 줘야 하는 문자가 아니었으니, 당시의 도스용 프로그램들처럼 효율적인 조합형 한글 입출력 메커니즘이 쓰이지 않았다. 게다가 한국에서 완성형이 주류 표준이다 보니 다국적 소프트웨어라면 한글을 2350자 내지 11172자의 그림문자처럼 취급할 수밖에 없었기 때문이다.

물론 세월이 흐르고 흘러 지금은 언어에 따른 성능 격차는 없기에 앞서서 측정 자체가 무의미해진 건 사실이다. 지금은 성능 격차 때문에 일부러 영문 원판 소프트웨어를 찾아 쓸 필요는 없다. 그러나 비주얼 C++ 같은 프로그램은 어차피 아무나 쓰는 프로그램도 아니고, 핵심 용어들에 대한 어설픈 번역에 이질감과 거부감이 들어서 한글판을 안 쓴다고 보는 게 타당하겠다.

단적인 예를 들어 보겠다. 아래 스크린샷을 보라.

사용자 삽입 이미지

먼저, output 창에 있는 컴파일 에러 로그를 보자. Illegal case를 '대/소문자가 잘못되었습니다'라고 오역한 건, 비주얼 C++이 처음으로 한글화된 200x 이래로 지금의 무려 2010에서까지 고쳐지지 않았다. 번역자가 C++ 프로그래밍에 전혀 무지하거나, 이 문장이 어느 문맥에서 쓰이는지를 하나도 알지 못한 채 번역했음이 분명하다. 세상에 C++이 컴파일러 차원에서 코드의 대소문자 오류를 분간해 주는 언어였던가. ㄲㄲ

비주얼 스튜디오 2010은 C#에 이어 C++까지도 코드의 오류가 있는 부분에 빨간 점선을 그어 준다. 물론 C++ 코드는 C# 코드보다 분석하기 훨씬 더 힘들기 때문에, 이는 내부적으로 완전한 형태의 컴파일러를 백그라운드로 돌림으로써 상당한 양의 CPU 오버헤드와 디스크 용량을 대가로 치른 끝에 구현된 편의 기능이다.

마우스를 case문 에러가 있는 곳으로 가져가 보면, 에러 메시지가 뜻밖에도 컴파일러가 뱉은 것과는 표현이 다르다. 그런데 '스위치'라고? 이건 case를 대소문자라고 옮긴 것보다는 덜 심각한 오역이지만, 이 역시 번역자가 문장을 제대로 이해를 못 하고 번역한 것 같다. 혹시 기능을 켜고 끄는 물리적인 스위치를 생각한 건 아닐까? 스위치를 음역하지 말고 그냥 'switch문'이라고 옮기는 것이 더 정확할 것이다.

2. 비주얼 스튜디오 2010의 GUI customization

비주얼 스튜디오와 MS 오피스 제품(지금처럼 리본 UI가 도입되기 전)은 그야말로 자신만의 화려하고 강력한 GUI를 갖추고 있었다. 메뉴와 도구모음줄은 운영체제가 자체 제공하는 녀석이 아닌 독자 구현 버전을 썼으며, 정말 과잉 투자 잉여라는 생각이 들 정도로 모든 GUI 구성 요소를 사용자 입맛에 맞게 바꿀 수 있었다. 도구모음줄의 배치는 두말 할 나위도 없고, 등록해 놓을 명령, 그리고 심지어 아이콘 그림과 기능 명칭까지도!

내 기억이 맞다면 이거 원조는 MS 오피스 97이다. BCG나 Xtreme toolkit처럼 이런 GUI 엔진만 짝퉁으로 구현하여 미들웨어 형태로 파는 업체도 응당 있을 정도였다.

이런 GUI 엔진이 탑재된 프로그램은 메뉴에 Tool(도구) - Customize(사용자 지정)라는 명령이 있었고, 이 대화상자는 약간 특이하게 동작을 했다.
보통 modal 대화상자가 떠 있는 동안은, 상위의 응용 프로그램 윈도우는 그 대화상자를 닫을 때까지 전혀 반응을 하지 않게 된다.
그런데 그 Customize 대화상자는 비록 modal 형태이지만, 그게 떠 있는 상태에서 마우스로 도구모음줄을 클릭하거나 메뉴를 누르면 도구모음줄이 반응을 했다. 도구모음줄 아이콘을 드래그하여 배치를 바꾸거나 없애거나, 콤보 상자의 경우 폭을 조절할 수 있고 우클릭하여 아이콘이나 설명문을 고칠 수 있었다.

즉, 평소에 도구모음줄을 우클릭하면, 나타내거나 감출 도구모음줄을 선택하는 메뉴만 뜨지만, Customize 중에 도구모음줄을 우클릭하면 해당 도구모음줄 아이콘을 고치는 더 세부적인 명령이 떴던 것이다.
메뉴에서 자주 쓰는 기능을 도구모음줄에다가도 좀 올려 놓으려면, 메뉴를 연 뒤에 해당 기능을 원하는 도구모음줄에다가 Ctrl+드래그만 하면 끝이었다.

사용자 삽입 이미지

그런데... 그런데... 비주얼 스튜디오 2010은 GUI 엔진이 싹 바뀌면서 저런 예외적이고 특이한 기능을 다시 구현하기가 대략 곤란했는지..
Customize 대화상자와 도구모음줄이 자연스럽게 연동하는 기능이 완전히 없어졌다.
대화상자가 떠 있는 동안은 도구모음줄을 전혀 건드릴 수 없다.

도구모음줄을 고치는 걸 전적으로 대화상자 안에서만 해야 한다.
내가 원하는 명령을 도구모음줄에다가 좀 추가하려고 했는데, 내가 원하는 도구모음줄과 내가 원하는 명령을 일일이 복잡한 리스트에서 찾으면서 정말 불편하고 번거롭기 그지없었다.
그리고 콤보 상자(빠른 찾기, 솔루션 플랫폼, 빌드 configuration 바꾸는 것 등)의 폭을 좀 바꾸려고 했는데 세상에나...
폭을 픽셀 단위 숫자로 입력해야 한다. -_-

사용자 삽입 이미지

예전에는 마우스 드래그로 간편하게 됐던 것이 상당히 퇴보한 게 아닐 수 없다..;;
난 개인적으로 GUI 운영체제에서, 화면으로 결과를 당장 볼 수 있는 값을 숫자 하나 달랑 입력받게 해 놓은 UI를 싫어한다. 가령, 객체를 회전하는 것만 해도 MS 오피스는 회전축을 잡고 마우스로 드래그함으로써 결과를 실시간으로 보면서 쉽게 할 수 있는데, 아래아한글 2007은 각도를 숫자로 입력해야 하고, 만족스러운 각도가 나올 때까지 사용자가 시행 착오를 겪어야 한다.;;

그런데 그런 불편한 방식을 비주얼 스튜디오 2010이 답습한 셈이다.
Customize 기능을 없앨 수는 없으니까, 그냥 이런 형태로 대충 대체 UI를 집어넣은 거라는 인상을 지울 수 없다.;;

딱 하나 좋아진 게 있다면,
예전의 customize 방식은 편리한 대신, 편법 UI인 만큼 오로지 마우스로만 접근 가능하고 키보드로는 하는 게 아예 불가능했는데 이제는 대화상자를 다루는 것이니 키보드로도 얼마든지 가능해졌다는 것.
사실, 가장 이상적인 건 둘을 모두 갖추는 것이긴 한데 이건 비주얼 스튜디오 2010에서 아쉬운 면모가 아닐 수 없다.

아울러 덧붙이자면, VS 2010도 Alt+F11을 눌러서 매크로 편집기를 열어 보면 그건 하나도 안 바뀌었고 예전의 VS 2008 IDE가 거의 그대로 뜬다.

Posted by 사무엘

2011/11/21 08:32 2011/11/21 08:32
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/602

전산학 전공자 내지 IT 분야 종사자에게는 상식으로 통용되는 당연한 개념이다만..
오늘날 범용(generic-purpose) 컴퓨터에서 돌아가는 소프트웨어는 크게 세 가지 형태로 나뉜다.

1. 로컬

흔히들 PC로 대표되는 컴퓨터에서 stand-alone으로 동작하는 전통적인 프로그램이다. Windows야 그렇다 치더라도 오피스, 비주얼 스튜디오 같은 업무용 프로그램은 아직 로컬 프로그램의 아성을 무너뜨릴 영역이 없다.
가장 역사가 길고, 가장 빠르고 효율적으로 동작하며, 특정 컴퓨터 아키텍처(기계어)와 운영체제의 실행 파일 포맷에 종속적이다. 그래서 이쪽 개발 환경은 전통적으로 C/C++ 같은 저수준 최적화 언어가 강세이다.

물론 클라이언트가 아닌 서버 프로그램은 성격이 약간 다르긴 하나, 서버 프로그램 자체는 역시 서버라는 로컬 컴퓨터 자신의 자원만을 이용하여 동작한다. 여객 운송과 화물 수송의 차이와 비슷한 맥락이다. 그리고 사실은, 다음에 설명할 2.웹 프로그램을 돌려 주는 기반도, 클라이언트든 서버든 1.로컬 프로그램들이 다 마련해 주고 있다. 그러니 로컬 프로그램은 앞으로도 없어질 수는 없다. 단지 전체 소프트웨어에서 차지하는 비중이 줄어들 뿐이다.

옛날에는 불특정 개인 사용자를 대상으로 하는 상업용 제품은 패키지 형태로 발매되곤 했지만, 오늘날은 인터넷의 발달과 극심한 불법 복제로 인해 이런 전통적인 형태의 배포의 비중이 굉장히 줄어들었다. 오늘날 국산 패키지 소프트웨어는 아래아한글과 V3 말고 있나? -_-;; 또한 보안 위협으로 인해 이런 프로그램 역시 한번 설치하고 끝이 아니라 끊임없는 보안 패치와 업데이트의 필요성이 커져 있기도 하다.

2. 웹

개인용 컴퓨터의 성능이 굉장히 향상되고 그에 따라 웹 표준이 발달하면서 웹브라우저, 정확히 말해 WWW는 단순히 그림과 하이퍼링크가 동원된 문서라기보다는 거의 프로그래밍 플랫폼처럼 오래 전부터 바뀌었다.

웹 프로그래밍의 최대 매력은 로컬을 월등히 능가하는 범용성과 기계 독립성, 생산성이다. 브라우저에서 사이트 접속만 하면 바로 실행..;; 마치 게임처럼, 클라이언트와 서버, 코딩과 디자인 등을 두루 아우르는 종합 예술처럼 보이기도 한다. 가령, 옛날에는 GWBASIC이나 LOGO로 어린 학생들에게 그래픽 프로그래밍 교육을 시켰다면, 지금은 그냥 HTML5만 써도 될 것이다.

물론, 로컬 개발에 비해서는 혼자 독립적인 작품을 만든다는 느낌이 좀 덜 들며-_-, 기술이 아직까지 안정화해있지 않은 면모가 있고, 로컬 컴퓨터 자체를 세밀하게 제어할 수 없으며 성능이 떨어진다는 한계도 있다. 가령, 오피스 제품군이 웹 애플리케이션으로 완전히 대체될 날은 과연 글쎄?
그러나 앞으로 웹 프로그래밍의 비중은 절대 무시 못 할 것이고 수요도 없어지지 않을 것이다.

3. 앱

스마트폰에서 동작하는 '로컬' 프로그램이라고 볼 수 있지만, 그 성격이 역시 1과는 사뭇 다르다.
스마트폰 자체는 PC보다 성능이 떨어지기 때문에, 로컬에서 모든 처리를 마친다기보다는 서버에다 input을 보내서 받은 output을 보여주는 형태의 앱이 많다. 또한 스마트폰은 화면이 작고 PC 같은 빠른 문자 입력을 할 수 없기 때문에, PC와는 다른 독자적인 GUI가 필요하다. 터치스크린은 마우스와 완전히 동일한 포인팅 UI가 아니다. (대표적으로 hovering이란 게 없다) 다만, PC에는 없는 기울임, 흔들림, 방향, 현재 위치 같은 특수한 입력을 받아들일 수 있다.

스마트폰은 PC만치 사용자가 컴퓨터 내부를 완전히 손쉽게 제어할 수 있는 물건은 아니다. 그래서 PC용 프로그램보다는 더 엄격한 과금 체계를 갖추고 프로그램을 배포하여 수익을 낼 수 있다.
스마트폰 앱은 역사가 짧기 때문에 PC 같은 지저분한 호환성 잔재 같은 게 덜하고, 일찍부터 자바든 C#이든 객체지향 언어와 가상 기계 바이트코드 기반의 프로그래밍 환경이 잘 구축돼 있다. 깔끔한 최신 프로그래밍 인프라가 기본으로 제공된다는 뜻이다.

오늘날 스마트폰 CPU는 ARM 아키텍처밖에 없지만, 그래도 커널 말고 다른 응용 프로그램들은 네이티브 코드가 아니다. 그런 .NET이나 자바 같은 가상 기계 자체가, 1~3(로컬, 웹, 앱) 사이의 이질감을 낮추고자 만들어진 것이기도 하고 말이다.
아울러, CPU의 성능이 좋아졌을 뿐만 아니라 LCD 디스플레이 소자가 보편화하고 통신 기술이 발달하면서 스마트폰 같은 물건도 대중화될 수 있었다.

20세기 중반까지만 해도 컴퓨터는 곧 메인프레임-단말기 모델이었다.
컴퓨터라는 게 무진장 비싼 물건이고 자원이 귀하다 보니, 모든 처리는 중앙 컴퓨터에다 맡기고 각 사용자는 단말기로 서버에 접속해서 명령 프롬프트에서 서버의 기능을 사용하곤 했다. 그때는 컴퓨터는 대학, 연구소, 정부 기관, 군대의 전유물이었고, 개인용 컴퓨터라는 개념을 감히 떠올리기조차 쉽지 않았었다. (알파넷이 미국이 아닌 소련에서 발명되었다고 생각해 보자. 그게 오늘날의 인터넷으로 발전할 수 있었을까? -_-)

그러다가 20세기 말에는 PC가 대세가 되었다. 개인용 컴퓨터 하나만으로 어지간한 일은 다 할 수 있게 되었다. 비유하자면, 만원버스에 시달리면서 출퇴근하다가 번듯한 자가용이 생긴 셈.
PC의 사고방식으로는 소위 PC 통신은 어쩌다 한 번씩만 다른 컴퓨터에 접속하는 특별한 작업이며, 웹브라우저 역시 오피스 패키지처럼 별도로 구입해서 사용하는 특수한 프로그램일 뿐이다.

그 후 오늘날 대세라고 회자되고 있는 건 일명 클라우드 컴퓨팅이다. 개인용 컴퓨터가 무진장 작아지고 통신 인프라가 발달한 덕분에, 예전처럼 부족한 자원을 공유하려고 컴퓨터들을 연결하는 게 아니라 진짜 유비쿼터스 세상이 돼서 컴퓨터들을 연결한다. PC 통신 시절에만 해도 하이텔 단말기가 있었는데 오늘날의 스마트폰에 비하면 얼마나 격세지감인가!

전세계 컴퓨터가 다 인터넷에 연결되고 클라이언트와 서버의 구분이 무의미해지고, 궁극적으로는 (거의) 모든 작업이 웹 프로그램만으로 해결되고 모든 자료가 웹에 저장되는 세상이 온다. 예전에는 PC끼리 자료 전송을 위해서 플로피 디스켓이나 USB 메모리를 썼는데, 이제는 사용자의 로컬 컴퓨터나 스마트폰 그 자체가 플로피 디스켓이나 USB 메모리와 마찬가지가 된다는 뜻.

이걸 역시 자동차에다 비유하자면 이렇다. 사람이 직접 자가운전을 하니까 교통사고가 발생하고 도로가 막히고 여러 문제가 생기다 보니, 전세계 도로가 한데 통제되고 지능형 임대 자가용이나 궤도 교통수단이 생겨서 모든 사람들이 그걸 간단히 이용하는 형태가 된 셈이다.
물론 이게 온전히 실현되려면 시스템적으로나, 보안 쪽으로나 해결해야 할 문제가 많다.

Posted by 사무엘

2011/10/14 08:26 2011/10/14 08:26
, ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/584

비주얼 C++ 2010 써 보다

* 옛날에 썼던 이 글과 연계되는 내용이다.

비주얼 스튜디오 2010을 드디어 회사에 깔아 봤다. 극심한 뒷-_-북.
인터넷 익스플로러 9만 보고도 “세상에 MS가 이런 UI의 프로그램도 만들다니, 오래 살고 볼 일이다”란 생각을 한 적이 있는데, VS 2010도 과연 그러하다.
개인적으로 시커먼 남색 배색이 별로 마음에 들지는 않다만..;;. 어째 이런 비주얼을 만들 생각을 했을까 싶다.

듣던 대로 IDE의 GUI 껍데기는 밑바닥부터 완전히 바뀌어서 다시 작성되었다.
닷넷 200x 시절은 비록 비주얼은 살짝 다를지언정 그래도 MS 오피스 엔진의 흔적이 남아 있었고 닷넷 초창기 버전인 2002/2003은 아예 오피스 XP의 GUI를 그대로 차용했었는데, 이제 비주얼 스튜디오의 GUI는 오피스와는 전혀 관계 없는 독자적인 엔진 기반이다.
그러고 보니 비주얼 C++ 6은 MFC를 사용하여 오피스와는 관계 없는 독자적인 GUI였는데... ^^;;

윈도우 운영체제의 모든 GUI는 메뉴에서 상하 화살표를 누르고 있으면, 비록 사용 불능(disabled)이라 할지라도 모든 항목이 순서대로 순회된다. 난 이게 MS 사의 전통인가 싶었다. 운영체제의 표준 메뉴부터 시작해 MS 오피스 등 MS에서 만든 역대 제품들을 모두 살펴보기 바란다.
그러나 VS 2010의 메뉴는 불능 항목는 아예 선택되지 않고 skip된다. 이 점에서는 과거 도스용 아래아한글의 동작과 비슷해졌다.

하다못해 이런 사소한 메뉴 GUI의 동작에서부터도 본인은 MS에서 만든 프로그램 같지 않은 이질감이 곧바로 느껴졌다.
덧붙이자면 VS 2010의 메뉴는 언제나 화면이 확 펼쳐지지 Fade나 Slide 같은 애니메이션 효과가 나타나지도 않는 것 같다.

IDE의 로딩 시간과 덩치는 확실하게 크고 아름다워졌다.
단, 인텔리센스는 확실히 예전 버전보다 더 똑똑해진 게 느껴져서 편하다. *.ncb 파일 대신 다른 방식의 인텔리센스 DB를 쓰는데, 역시 프로젝트 하나당 수십 MB씩 용량을 무지막지하게 차지하는 건 변함없다.
닷넷 시절 거의 10년 가까이 사용해 온 Document Explorer 기반 도움말(MSDN) 시스템도 갈아엎었다고 하는데 자세한 내역은 잘 모르겠다. 단, 매크로 IDE는 과거의 비주얼 스튜디오 2008 IDE를 그대로 쓰고 있음.

프로그래머용 에디터에 화면 확대/축소 기능이 생겨서, 단순히 글씨 크기만 바꿀 때는 옵션 대화상자를 꺼낼 필요가 없게 된 건.. 상당히 참신하다. 그래도 조절을 할 수 있으니까 유용하다.
<날개셋> 편집기도 글씨 크기 조절 기능 건의가 지금까지 한두 번 들어온 게 아니니 말이다. =_= (하지만 프로그램의 구조와 개발 방향의 특성상, 실현 가능성은 제로)

뭐, IDE와 GUI 얘기는 여기까지 하고...
비주얼 스튜디오는 2005 이후에 3이 더해진 2008 버전보다도, 2가 더해진 2005나(2003에서 버전업) 2010이(2008에서 버전업) 변화 사항이 많았다.
다만, 2003과 2010은 그 해 4월에 출시되었고 2005는 그 해 말(10~11월), 그리고 2008은 아예 2007년 말에서 2008년 초에 가깝기 때문에 실제 출시 간격은 2년 반에서 큰 차이가 없다고 볼 수도 있겠다.

역사적으로 MS 제품들이 2000년대 중반에 운영체제는 XP와 비스타 사이, 오피스는 2003과 2007 사이, IE는 6과 7 사이에 간격이 굉장히 길었다. 이에 반해 비주얼 스튜디오는 그런 제품들과는 무관하게 버전업이 꾸준히 되어 온 셈이다.

과거 MSVCR71.DLL, MFC71.DLL에 이어, MSVCR100.DLL과 MFC100.DLL도 이젠 그냥 편하게 윈도우 시스템 디렉터리에 들어가 있다. 정말 감개무량하다. VS 2005와 2008이 사용하는 CRT/MFC DLL만(80, 90) 잠깐 winsxs 밑으로 숨었었는데, 그 방식이 배포하기가 너무 불편해서 다시 일반 DLL 로딩 방식으로 되돌아간 것이다.

VC 6의 유물이던 클래스 마법사가 다시 생긴 것도 신선한 충격. 굳이 MFC 기반 프로젝트가 아니어도 유용해 보인다.
하긴, 6 시절까지만 해도 클래스 마법사가 효율적으로 소스를 파싱하라고 메시지 맵에 //AFX_MSG 같은 이상한 주석 부호도 있었는데.. 그게 필요 없어진 게 닷넷부터이다.

VC 2010은 모처럼 C++ 언어 문법도 제법 확장되었으니 이것도 짚고 넘어가지 않을 수 없겠다.

auto와 nullptr은 가뭄에 단비 같은 유용한 키워드이다.
전자는 본인이 예전에도 논평했듯이, 번거로운 타이핑과 typedef를 획기적으로 줄여 준다.
그리고 후자는 숫자로 쓰이는 0과 포인터로 쓰이는 0을 확실하게 구분하여 C++ 함수의 오버로딩 때 모호성을 해소해 준다. explicit과 비슷한 맥락에서 추가되었다고도 볼 수도 있겠다.

다만, 기존 코드와의 명칭 충돌을 최대한 피하기 위해 null이나 NULL, 심지어 nil도 아닌 nullptr로 예약어가 정해졌다는 건 감안할 필요가 있음.
또한, 기왕 auto가 추가됐을 정도면 상위 클래스를 자동으로 가리키는 super 같은 키워드도 C++에 같이 좀 추가하지 하는 아쉬움이 있다. 비주얼 C++은 MS 확장 차원에서 __super가 있긴 한데 말이다.

문득 드는 생각인데, 순수 가상 함수를 선언할 때 쓰이는 0은 숫자에 가까울까, 포인터에 가까울까?
숫자의 성격이 강하다면 0 대신 false를 써도 되겠고, 포인터의 성격이 강하다면 0 대신 nullptr을 쓰면 되겠다. 하긴, true와 false는 진작부터 C++ 예약어로 추가됐는데 말이다. 이제 C++에는 0을 의미하는 키워드가 둘 존재하게 됐다.

뭐, 요약하자면, 덩치가 딥다 커졌는데, 커진 만큼 덩치값 하는 편의 기능도 많고 기능면에서 바뀌고 향상된 것도 많다. 다만, 비주얼은 내 눈에는 여전히 좀 이질적임. ㅋㅋ
간단하게 VC 2010으로 <날개셋> 한글 입력기 프로젝트를 빌드도 해 봤다. 개발용으로는 2010으로 언제쯤 완전히 갈아탈지는 미지수이다.

<날개셋> 한글 입력기는 1.x부터 2.4까지는 VC 6.0을 썼고, 2.5부터 5.3x까지는 6년 동안 VC 2003을 썼다. 그러다가 5.5부터는 지금까지 약 2년간 VC 2008을 쓰는 중. 2005는 64비트 에디션을 빌드할 때만 잠깐 쓰다가 이마저도 2008로 곧 대체됐다. ^^;;

난 개인적으로 비주얼 C++에 대해 실현 가능성이 별로 없는 두 가지 희망 사항이 있다.

첫째, MFC나 플랫폼 SDK 같은 공통 프로그래밍 요소들의 인텔리센스 정보들은, 매번 번거롭게 각 프로젝트별로 중첩해서 들어가는 게 아니라 이미 만들어져 있는 걸 공유할 수 있으면 좋겠다. 이것만 해도 인텔리센스 파일 크기가 엄청나게 줄어들 것이다. -_-;;

그리고 둘째, 운영체제의 legacy known DLL인 msvcrt.dll과 mfc42.dll에다가 바로 링크하는 기능도 좀 있으면 좋겠다. 런타임 dll을 배포하지 않고, static link 하지 않고도 작은 바이너리 배포를 할 수 있게 말이다.

덩치가 커지는 것 자체가 문제가 아니라, '불필요하게' 덩치가 그것도 꽤 부담될 정도로 커지는 게 문제이다. I hate bloatwares. -_-

Posted by 사무엘

2011/08/13 08:11 2011/08/13 08:11
,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/554

윈도우 운영체제가 제공하는 파일 목록 탐색 API로는 FindFirstFile, FindNextFile가 있다.
사실, 도스 시절에도 C언어에는 내부적으로 도스 API를 사용하는 _findfirst, _findnext 같은 함수가 있었는데, 윈도우 API 역시 그 인터페이스를 거의 그대로 차용했다.

파일을 탐색하는 동작은 state가 존재하는 costly한 작업이기 때문에, 파일을 여닫는 것처럼 핸들을 주고받는 과정이 수반되며, 탐색이 끝나고 나면 그 핸들을 반드시 닫아 줘야 한다.
state가 존재하는 덕분에, 파일 탐색을 하는 도중에 다른 디렉터리에 대해 다른 파일 탐색 작업을 시작할 수도 있다. 이게 가능해야 재귀적으로 하위 디렉터리 다단계 탐색을 할 수 있을 것이다. 참고로 C 표준 함수 중 strtok 함수는, state가 존재함에도 불구하고 state 핸들값을 별도로 받지 않아서 디자인상 문제가 있는 함수라고 까였음..

본인은 운영체제가 제공하는 파일 탐색 함수의 인터페이스에 대해 다음과 같은 불만이 있다.
먼저, 파일 탐색 동작을 식별하는 핸들값 HANDLE과, 파일이 계속 존재하는지를 판단하는 BOOL값을 따로 관리해야 한다는 것이다. FindFirstFile은 HANDLE을 되돌리고, FindNextFile은 BOOL을 되돌린다. 그래서 이들을 가지고 for문이라도 만들려면 두 변수를 모두 갖고 있어야 한다. (말만으로는 실감이 잘 안 갈 테니, 관심 있으신 분은 파일 탐색 루틴을 직접 짜 보기 바란다.)

MFC의 CFileFind는 기존 API 함수를 거의 그대로 캡슐화했지만 다행히 FindFirstFile에 해당하는 FindFile 함수도 동일하게 FindNextFile과 마찬가지로 BOOL을 되돌려서 그나마 낫다.
또한 소멸자는 자동으로 FindClose를 호출해 주며, 지금 찾은 파일에 대한 정보를 별도의 GetFilePath 같은 멤버 함수를 통해 얻어 올 수 있다. 그래서 아래와 같은 형태로 loop을 작성하면 된다.

CFileFind fnd; BOOL b;
for(b=fnd.FindFile(L"*.txt"); b; b=fnd.FindNextFile())
  Use(fnd.GetFilePath());

본인은 한술 더 떠서 이렇게 독자적으로 만든 클래스를 즐겨 사용한다. 생성자와 소멸자를 빼면 다들 연산자 오버로딩이다.

class CMyFileFind {
public:
  CMyFileFind(PCTSTR pszFile);
  ~CMyFileFind();
  const WIN32_FIND_DATA *operator ->() const;
  operator bool() const;
  void operator++(int);
};

for(CMyFileFind fnd(L"*.txt"); fnd; fnd++)
  Use(fnd->cFileName);

짠~
파일 탐색을 생성자에서 바로 시작할 수 있고, WIN32_FIND_DATA에 파일 정보가 존재하는지의 여부를 bool 형변환 연산자가 바로 알려준다. 그리고 ++ 연산자가 다음 파일 탐색을 의미하며, -> 연산자를 통해 찾은 파일 정보를 곧바로 얻을 수 있다. 깔끔하지 않은가? ㄲㄲ

개인적으로, FindNextFile 함수는 더 발견된 파일이 없는 경우 주어진 찾기 핸들을 자동으로 close해 버리는 기능도 있으면 좋겠다.
파일 탐색 기능에 앞으로 되돌아가는 기능이 있는 것도 아닌데(=PrevFile 같은 거라도..;;), 더 찾을 파일이 없으면 이 핸들은 닫아 버리는 것 말고 도대체 다른 용도가 있는가? 놔 둘 이유가 전혀 없다.
이렇게 되면 파일을 찾다가 중간에 멈추는 게 아닌 이상, FindClose를 번거롭게 또 호출해야 할 필요가 없어져서 좋을 것이다.

이 찾기 핸들의 자료형은 HANDLE이다. 하지만 파일이나 스레드 같은 커널 오브젝트가 아니어서 그런지, CloseHandle이 아니라 반드시 FindClose 함수로 닫아야 한다. 그리고 실패를 의미하는 값이 NULL이 아니라, 마치 CreateFile의 실패값처럼 INVALID_HANDLE_VALUE (-1)이다. 이런 인터페이스가 뒤죽박죽인 건 윈도우 API의 디자인 결함인 것 같다. memory-mapped file을 만드는 CreateFileMapping의 실패값은 또 NULL임.. -_-;;

또한, 파일과 디렉터리를 구분 없이 찾는 것도 개인적으로 무척 불만이다.
그래서 이 탐색 결과를 담고 있는 구조체에 대해서 dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY 체크부터 꼭 해 줘야 한다.
또한, 이런 디자인으로 인해, 어떤 디렉터리 내부에서 파일은 *.txt 같은 와일드카드로 찾고 디렉터리는 와일드카드 없이 다 찾으려면 검색을 두 번 수행해야 한다. 디렉터리 이름은 언제나 전체 검색이지 이걸 와일드카드로 찾는 일은 오늘날 전혀에 가깝게 없기 때문이다. DIR *.txt /S 같은 걸 구현하는 걸 생각해 보면 쉽게 이해가 될 것이다.

와일드카드를 해석하는 작업은 보통 운영체제가 알아서 해 준다. 하지만 도스와 윈도우는 전통적으로 이 알고리즘이 굉장히 단순하기 그지없어서 * 같은 경우 문자열의 뒤에만 붙일 수 있다. A*T.*P 같은 식의 패턴을 쓸 수는 없다는 뜻.
하지만 프로그래밍 언어나 런타임의 제작사에 따라서는 파일 탐색 기능을 제공하면서 와일드카드 해석은 독자적으로 하는 경우도 있다. 가령, 파이썬은 운영체제의 와일드카드 해석 루틴을 사용하지 않으며, 도스에서 구동되던 DJGPP도 디렉터리 아예 구분자로 \ 대신 유닉스처럼 /를 쓰는 등, 파일 경로 해석 자체를 독자적으로 한다.

이상 파일 탐색 관련 잡설이었다.
파일에서 뭔가 검색, 탐색을 한다고 하면 파일 내부에 있는 특정 문자열을 검색하는 것과, 파일 목록을 추출하는 것, 그리고 열어 놓은 파일 내부에서 읽거나 쓰는 지점을 이동하는 seek가 모두 가능하다.
그리고 특정 파일에 대해서 크기나 날짜 같은 부가 정보를 얻는 기능은, 열어 놓은 파일 핸들을 상대로 수행하는 것과 파일을 열지 않고 수행하는 것이라는 두 양상으로 나뉜다는 특징이 있다.

Posted by 사무엘

2011/07/29 08:32 2011/07/29 08:32
, ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/547

« Previous : 1 : ... 20 : 21 : 22 : 23 : 24 : 25 : 26 : 27 : 28 : ... 31 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/12   »
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:
3043082
Today:
274
Yesterday:
2435