C++에 들어왔다면 바로 이 객체라는 것을 이해할 필요가 있습니다.

OOP(Object Oriented Programming) 라고 불리는 이 내용은 물론 단순하게
C++이라고 이야기할 수도 있지만, 더 광범위한 부분입니다.
OOP는 객체라는 개념으로 시작한 일종의 명세서 같은 것입니다.
이 명세서를 기반으로 C를 확장한것이 바로 C++입니다.
흔히 JAVA를 이야기하는데, 오히려 OOP에 가까운 것이 바로 JAVA입니다.
더 가까운것은 smalltalk 이구요.

자 그렇다고 OOP를 하기 위해서라면 위의 언어들을 통달해야 하냐?
그것은 아닙니다. 모로가도 서울로 가면 된다는 말이 있듯이
어떤 말로 하든 원하는 기능을 구현할 수 있다면 아무런 문제가 없습니다.

단지 여기서는 수많은 OOP 언어중 C++을 택한 것 뿐입니다.
자 이정도로 거두를 하고.. 객체에 대해서 이야기하죠.

객체란 데이터(Data)와 함께 실행할 수 있는 메소드(Method)가 있는 것입니다.
이것이 가장 기본적인 유형이자 형태 인데, 저리 말을 해놓고 보면 쉬이 이해가 안될 수도 단빡에 이해할 수도 있습니다.

자, 이 것은 Microsoft에서 객체를 설명하기 위한 예제였습니다.
풍선이 있습니다.

풍선을 가만히 바라 보면 여러가지를 판단해 낼 수 있습니다.
먼저 다양한 유형, 또는 모양의  풍선이 있습니다.
크기, 색, 바람넣은 양에 따라 그 풍선을 정의할 수 있습니다.
또 풍선을 가지고 할 수 있는 일들이 있습니다.
먼저 풍선에 바람넣기 빼기, 던지기, 터트리기, 띄우기 등입니다.

자, 위의 이야기를 근거로 무엇을 단빡에 알아낼 수 있을까요? 객체지향에 대해서 조금이라도 이해하고 계신분은
바로 나올 것입니다.
먼저 이야기한 다양한 유형/모양이 바로 DATA 입니다.
그리고 가지고 할 수 있는 일이 바로 Method 입니다.

이런 객체를 정의할 때 아래와 같이 정의하는 것이죠.

* 풍선
- Data
  색
  크기
  바람 넣은 양

- Method
  바람 넣기
  바람 빼기
  띄우기
  던지기

하지만, 이것은 우리가 개념적으로 생각하는 내용입니다. 풍선이라는 것을 정의했지만
실제 풍선이 아닙니다. 헷갈리죠?
존재하는 풍선과 개념적인 풍선과의 차이를 이해할 수 있다면 쉬이 아아.. 하겠지만, 그렇지 않다면
쉬이 이해할 수 없는 것입니다.

다른 예제로 들죠.
건물이 있습니다. 건물을 지으려면 수많은 공정이 있겠지만, 단순하게 생각하면 두개로 나눌 수 있습니다.
설계하는 작업 / 건물 짓는 작업.
설계에서는 높이도 있고 층도 있고 다양한 내용이 들어 갈 수 있습니다.
이렇게 하는 일들이 있겠구나 하면서 이런 저런 기능도 넣게 됩니다.
건물을 짓는 일은 바로 그 설계를 보고 실제 콘크리트를 넣고 실제 층수로 올리고 이런 저런 기능을
위한 작업을 합니다.

자 여기서 설계작업때 도면에 그린 건물에서 실제 실생활에 그 건물을 사용하실 수 있나요?
못하죠? 실제 건물을 지어야 그 안에서 벽지도 바꿔 보고, 외면의 타일도 바꾸고 그 안에서 주거 할 수 있게되죠?

이 개념을 잊지 말아야 합니다.
여기서 객체라는 것을 정의하는 것은 두가지라는 것을 기억하세요. Data 와 Method
그리고 그 객체를 실존시키는 작업이 필요하다는 것도 기억하세요. 이것이 바로 instance 입니다.

정의하는 것과 instancing(instance 시키기/실존 시키기)는 엄연히 차이가 있습니다.

여기서는 네가지를 배우게 됩니다.
객체 = Object = Class
객체 구성요소 : Data , Method
객체의 실존화 : Instance

먼저 이렇게 기억을 해두세요.




728x90
내가 가진 지식의 정리라는 차원이 맞을 것입니다.
처음에는 WikiWiki에 기록해 나갈려고 했었는데, 이런저런 여건상 결국 게시판으로 돌아왔네요.

VC++ 을 처음 접하고 그것으로 이런 저런 작업을 하면서 느낀 것들입니다.
아마도 제가 죽더라도 이것을 남기면 좋을것 같기도 하고...

요즘은 4GL의 발전과 Web Server 기반 Scrpit의 발전으로 VC++의 입지는 상당히 앝은 편입니다.
하지만, C++이라는 개념에서 출발한 VC++은 정말이지 다양한 기능을 제공합니다.
간단히는 Windows App를 만드는 데서 ActiveX라는 장르로 Web 상에서 제어하는 것에
심지어는 Windows Kernel을 헤집어 놓을 수 있을 만큼 강력합니다.

하지만 강력한 만큼 툴 자체가 가진 기능을 사용하려면 망망 대해에서 무엇을 출발해야 될지
모르는 경우가 많습니다.
게다가, 너무도 넓은 길때문에, 전혀 다른 쪽의 작업을 하려면 쉬이 전환이 불가능한 경우가 많습니다.

아직 제가 하는 이야기를 잘 이해가 안될지도 모르고, 반박할지는 모르겠지만...
일단 제가 느낀 VC++ 아니, C++의 느낌은 그렇습니다.

타이틀은 비록 VC++이지만 C++이기도 합니다.

그점은 알아주시기 바랍니다.
728x90
WM_ 으로 시작하는 윈도우 메시지를 만들었을때, MFC에서 제공하는 On_ 으로 처리되는 함수들이
자동으로 생성되는 것 보면 편해보이기 까지한다.
이를 수동적으로 생성하는 방법을 알아보자.

WM_USERDEFINE 이라는 메시지가 있다고 하자.
사용자가 만든 메시지여서, 실제 MFC Wizard로 만들수 없다.
게다가, MessageMap 매크로 안에 넣으려해도, afxmsg OnUserDefine 을 만들려고 하면
그 함수와 Message와 연결 할 방법이 없다.
이를 처리하려면, MessageMap 안에서 함수와 Message를 연결해주는 무언가를 만들어 줘야 한다.
그리고, 각 함수를 살펴보면, 윈도우 메시지를 그냥 받는 것이 아니고 각 유형 별로 파라미터로 받는 경우가 있다.
예를 들자면 OnLButtonDown(UINT nFlags, CPoint point) 같은 것은 nFlags 나 point를 받는다.
하지만, 현재는 파라미터가 없는 버젼만을 생각하여 만들도록 하자.

WM_USERDEFINE을 가지고 한번 만들어 보자.

.H 을 열어 보면,
   //{{AFX_MSG(CUserDefine)
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
이라는 부분이 있다.
실제로 "//{{AFX_MSG(CUserDefine)",  "//}}AFX_MSG" 이 두 문장은 단순히 클래스 위자드에서 사용하기 위해
만들어진 내용이므로 삭제해도 무방하다. 단 클래스 위자드에 의존하는 분들은 이 부분을 지우게 되면 새로운 메시지
처리를 추가/삭제/수정이 절대 불가능하니, 조심한다.
일단, "//}}AFX_MSG" 아래에다 자신이 만든 메시지 핸들러 함수를 선언한다.
afx_msg 를 맨 앞에 붙이고 그 뒤에 함수 선언을 한다. On 이라는 이름이 붙은 형태의 함수를 만든다.
   afx_msg OnUserDefine()
그러면 .H에서 다 기록한 것이다.

.CPP를 열어보면,
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
가 보일 것이다. 이 안이 바로 Message와 함수를 연결해주는 부분이다. 그러나 그 안에 보면 단순히
ON_WM_PAINT()와 같은 단순 무식한 한줄의 함수만 보인다. 그렇다면 이를 어떻게 해야 하는 것인가?
간단하다. ON_WM..  시리즈를 직접 만드는 것이다.
   #define ON_WM_USERDEFINE()
   { WM_USERDEFINE, 0, 0, 0, AfxSig_vv,
   (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnUserDefine },
위의 세줄을 넣어준다.  이 부분이 바로 ON_WM 시리즈의 실체가 된다.
실제 사용되는 WM_ 메시지를 넣고 맨 뒤의 On.. 시리즈 함수를 대체해서 만들어 주면 된다.
위의 예제는 WM_USERDEFINE을 기준으로 넣었다. 그러면 BEGIN_... 안에다 자신이 만든것을 넣어 주면 된다.
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
                ON_WM_USERDEFINE()
   END_MESSAGE_MAP()
이렇게 하면 모든것이 해결!

파라미터가 있다면 그 뒤에 다시 생각해보도록한다.
참고로 AfxSig_xxx 라는 값을 이용하면 다양한 형태로 구성할 수 있는 데, 이는 정해진 내용만 적용가능하다.
        AfxSig_bD,      // BOOL (CDC*)
        AfxSig_bb,      // BOOL (BOOL)
        AfxSig_bWww,    // BOOL (CWnd*, UINT, UINT)
        AfxSig_hDWw,    // HBRUSH (CDC*, CWnd*, UINT)
        AfxSig_hDw,     // HBRUSH (CDC*, UINT)
        AfxSig_iwWw,    // int (UINT, CWnd*, UINT)
        AfxSig_iww,     // int (UINT, UINT)
        AfxSig_iWww,    // int (CWnd*, UINT, UINT)
        AfxSig_is,      // int (LPTSTR)
        AfxSig_lwl,     // LRESULT (WPARAM, LPARAM)
        AfxSig_lwwM,    // LRESULT (UINT, UINT, CMenu*)
        AfxSig_vv,      // void (void)

        AfxSig_vw,      // void (UINT)
        AfxSig_vww,     // void (UINT, UINT)
        AfxSig_vvii,    // void (int, int) // wParam is ignored
        AfxSig_vwww,    // void (UINT, UINT, UINT)
        AfxSig_vwii,    // void (UINT, int, int)
        AfxSig_vwl,     // void (UINT, LPARAM)
        AfxSig_vbWW,    // void (BOOL, CWnd*, CWnd*)
        AfxSig_vD,      // void (CDC*)
        AfxSig_vM,      // void (CMenu*)
        AfxSig_vMwb,    // void (CMenu*, UINT, BOOL)

        AfxSig_vW,      // void (CWnd*)
        AfxSig_vWww,    // void (CWnd*, UINT, UINT)
        AfxSig_vWp,     // void (CWnd*, CPoint)
        AfxSig_vWh,     // void (CWnd*, HANDLE)
        AfxSig_vwW,     // void (UINT, CWnd*)
        AfxSig_vwWb,    // void (UINT, CWnd*, BOOL)
        AfxSig_vwwW,    // void (UINT, UINT, CWnd*)
        AfxSig_vwwx,    // void (UINT, UINT)
        AfxSig_vs,      // void (LPTSTR)
        AfxSig_vOWNER,  // void (int, LPTSTR), force return TRUE
        AfxSig_iis,     // int (int, LPTSTR)
        AfxSig_wp,      // UINT (CPoint)
        AfxSig_wv,      // UINT (void)
        AfxSig_vPOS,    // void (WINDOWPOS*)
        AfxSig_vCALC,   // void (BOOL, NCCALCSIZE_PARAMS*)
        AfxSig_vNMHDRpl,    // void (NMHDR*, LRESULT*)
        AfxSig_bNMHDRpl,    // BOOL (NMHDR*, LRESULT*)
        AfxSig_vwNMHDRpl,   // void (UINT, NMHDR*, LRESULT*)
        AfxSig_bwNMHDRpl,   // BOOL (UINT, NMHDR*, LRESULT*)
        AfxSig_bHELPINFO,   // BOOL (HELPINFO*)
        AfxSig_vwSIZING,    // void (UINT, LPRECT) -- return TRUE

        // signatures specific to CCmdTarget
        AfxSig_cmdui,   // void (CCmdUI*)
        AfxSig_cmduiw,  // void (CCmdUI*, UINT)
        AfxSig_vpv,     // void (void*)
        AfxSig_bpv,     // BOOL (void*)

        // Other aliases (based on implementation)
        AfxSig_vwwh,                // void (UINT, UINT, HANDLE)
        AfxSig_vwp,                 // void (UINT, CPoint)
        AfxSig_bw = AfxSig_bb,      // BOOL (UINT)
        AfxSig_bh = AfxSig_bb,      // BOOL (HANDLE)
        AfxSig_iw = AfxSig_bb,      // int (UINT)
        AfxSig_ww = AfxSig_bb,      // UINT (UINT)
        AfxSig_bv = AfxSig_wv,      // BOOL (void)
        AfxSig_hv = AfxSig_wv,      // HANDLE (void)
        AfxSig_vb = AfxSig_vw,      // void (BOOL)
        AfxSig_vbh = AfxSig_vww,    // void (BOOL, HANDLE)
        AfxSig_vbw = AfxSig_vww,    // void (BOOL, UINT)
        AfxSig_vhh = AfxSig_vww,    // void (HANDLE, HANDLE)
        AfxSig_vh = AfxSig_vw,      // void (HANDLE)
        AfxSig_viSS = AfxSig_vwl,   // void (int, STYLESTRUCT*)
        AfxSig_bwl = AfxSig_lwl,
        AfxSig_vwMOVING = AfxSig_vwSIZING,  // void (UINT, LPRECT) -- return TRUE

        AfxSig_vW2,                 // void (CWnd*) (CWnd* comes from lParam)
        AfxSig_bWCDS,               // BOOL (CWnd*, COPYDATASTRUCT*)
        AfxSig_bwsp,                // BOOL (UINT, short, CPoint)
위에서 보듯이 딱 정해진 기능만 하므로... 그 외의 것이라면 다시 생각해보도록 한다.

PS. 혹여 AfxSig_lwl 를 사용하면 WPARAM, LPARAM 이니까... 다양하게 이용할 수 있을지도 모르겠다.

728x90
Linux에서 rdate라는 명령이 있다.
시간 서버에 접속해서 현재 Linux 의 시간을 설정하는 것이다.

이 명령을 보면, rdate -s 가 있는 time host에 접속해 서버 시간을 로컬 시간과 동일하게 만들어 준다.
Time 서버는 일반적으로 time.nist.gov를 사용하면 된다.

728x90
분 시 일 월 요일 권한자 실행내용
ex) 0 0 * * 0 root rdate -s time.nist.gov
   0시 0분 그것도 일요일만 실행을하면 실행권한은 root 이고, rdate 이하를 실행한다.  

/etc/crontab 안의 Text로 해당하는 처리를 하면 된다.
728x90
Winsock의 형태는 다양하게 변모되어 우리에게 다가왔다
sock 라이브러리를 Windows에 맞게 처음 도입한 Winsock 1.x에서 2.x로 발전하고,
MFC로 재 제작하여 배포하고 있다.

여기서 winsock 1.x 때와 2,x 때 include하는 내용이 틀리다.

1. 일반적으로 winsock1.x 라이브러리를 사용하려면,
winsock.h만 include하면 된다. (lib는 일반적으로 섞여 처리된다.)

2. winsock 2.x대에서는 다음의 추가적인 처리가 필요하다.
Winsock2.h 와 ws2tcpip.h 를 include 처리하고
ws2_32.lib를 link시 연결해 주면 된다.

3. MFC 인경우에는 MFC 4.x 대 library안에 lib는 내장되어 있고 단지, 해당 클래스만 include 처리하면 된다.
afxsock.h 가 바로 그 include해야 될 내용이다.
728x90
mysql 4.x를 RPM으로..
libiconv 도 prefix = "/usr" 로 설정하고 설치하고...
apache 1.3. x도 RPM으로 되었다면..
/usr/local/freetds 에 MSSQL 라이브러리를 설치하고 난뒤 사용한다.
Gd 라이브러리 포함(단 zlib를 RPM으로 설치되어 있어야함 )

./configure --with-apxs=/usr/sbin/apxs --with-imap=/usr --with-mysql=/usr --with-iconv=/usr --with-language=korean --with-charset=euc_kr --enable-track-vars --enable-module=so  --disable-cgi --with-config-file-path=/etc/httpd/conf --enable-versioning --with-kerberos --with-imap-ssl=/usr   --with-mssql=/usr/local/freetds --enable-msdblib --with-gd  --with-zlib-dir=/usr
728x90
Kernel Compile

  배경지식

기본적으로 커널 소스의 디렉토리는 /usr/src/linux 이다.
커널 컴파일 방법에는 3가지가 있다
make config -> 옵션을 잘못 선택하면 처음부터 다시해야하는 단점이 있다.
make menuconfig -> 가장 추천하는 방법(단, ncurses가 있어야 한다.)
make xconfig -> X에서 볼수 있다.( 화려하다. 그냥 구경한번 해보길...)
시스템 사양을 잘 알아야 한다.(이더넷 카드, 사운드 카드, CPU가 몇개(?)인지등...)
어떠한 환경에서 사용할건지 결정하여야 한다.(커널의 최적화를 위해...)
Kernel Compile Option
꼭 주의깊게 살펴볼것!!(나에게 어떤 옵션이 필요한지 볼것)
제 2회 리눅스 공동체 세미나 자료에서 추출(이규호님께 감사)
커널 2.4 Intro중 커널옵션설정
일반적인 데스크탑 PC사양에서 필요로하는 커널옵션들을 설명하고있다.
  따라하기

커널 소스를 받는다.( http://www.kr.kernel.org/pub/linux/kernel/)
소스를 /usr/src 방으로 옮긴다.(예: mv linux-2.2.12.tar.gz /usr/src )
전에 있던 커널소스 /usr/src/linux 디렉은 다른이름으로 바꾸던지 지워라.(예: mv linux linux-2.2.11)
만약 linux라는 이름으로 심벌릭 링크되어있다면 링크만 해제하라.(예: rm linux)
커널 소스를 푼다.(예: tar xvvzf 커널버전.tar.gz 또는 tar xvvIf 커널버전.tar.bz2)
linux라는 디렉토리가 생겼을 것이다. 그 디렉으로 들어간다.( cd linux )
# make menuconfig ( 현재 위치 /usr/src/linux )
커널 컴파일 옵션을 보고 시스템에 맞는걸 선택한다.(중요하다!)
# make clean (예전 오브젝트 파일 제거)
# make dep (의존성을 검사)
# make bzImage (커널 이미지를 압축생성한다.)
# mv arch/i386/boot/bzImage /boot/vmlinuz-커널버전 (예: mv arch/i386/boot/bzImage /boot/vmlinuz-2.2.12)
# mv System.map /boot/System.map-커널버전 (예: mv System.map /boot/System.map-2.2.12)
# vi /etc/lilo.conf ( 리로를 편집한다 )
     boot=/dev/hda
     map=/boot/map
     install=/boot/boot.b
     prompt
     timeout=50
     image=/boot/vmlinuz-2.2.12 -> 새로운 커널이미지를 linux라는
     label=linux              ?   레이블로 한다.
     root=/dev/hda1
     read-only

     image=/boot/vmlinuz-2.2.11 -> 혹시나 모를 커널 패닉에 대비하여          
     label=old                     예전 커널을 old란 레이블로 해놓는다.
     root=/dev/hda1                (예전 버전이 2.2.11일때)
     read-only
# /sbin/lilo ( lilo.conf의 내용을 인식시켜 주기위해 )
여기까지 커널 컴파일은 과정은 끝.
  모듈 인스톨 하기

커널 옵션에서 모듈(M)으로 선택한것을 컴파일 하기위해
# cd /usr/src/linux
# make modules
# make modules_install
위와같이 하면 '/lib/modules/커널버전' 디렉에 모듈들이 위치한다.


Kernel Patch


패치란 매번 커널이 바뀔때 마다 13MB가 넘는 커널 소스를 다시 받을 필요없이 바뀐 차이점만 담고있는 작은 용량의 파일로 커널을 업하는걸 말한다.
장점 : 적은용량으로 패치파일로 커널을 금방 업 할 수 있다.
단점 : 중간의 한 단계를 건너 뛸 수 없다. 예를들어 현재 커널 버전이 2.2.10 인데 바로 2.2.12로 패치 할 순없다.(꼭 2.2.11을 패치하고 나야 된다)
  따라하기

패치 파일을 다운받아 bzip2이든 gzip으로 압축되어있던지 간에 압축을 푼다.
압축을 푼후 /usr/src/linux 방으로 옮긴다.
# patch -p1 < 패치파일?
에러 없이 넘어가면 다음은 커널 컴파일 과정과 같다.
만약 압축을 풀지않고 패치하려면 gzip 또는 bzip2에 따라 다음과 같이한다.
# gzip -cd 패치파일.gz | patch -p1(물론 패치파일의 위치는 /usr/src/linux)
# bzip2 -cd 패치파일.bz2 | patch -p1
728x90

+ Recent posts

728x90