http://kkamagui.tistory.com 혼자서 커널 제작하시고(x86용) 운영체제도 만들고 책도 출판 하신 분.(우리회사 무선)
http://kldp.org/node/123910 arm용 운영체제 제작.



그리고...
http://uvicrabbit.tistory.com/ Windows 구조와 원리 를 출판하신 정덕영님...
매우 좋아하던 책. 언젠가 뵙고 싶었던 분인데.. 이제야 알았네요.

삼가 고인의 명복을 빕니다.

'Programming > __etc' 카테고리의 다른 글

옴니아 햅틱(진동) 프로그램  (0) 2010.04.05
C2146 구문오류  (0) 2010.03.18
패킷 만들기  (0) 2010.03.18
[참조: http://idrose1025.egloos.com/2628732]
[그림 참조: http://alghost.tistory.com/22
]

Doxygen 주석 사용법 


Doxgen은 많이 사용하고 있고 사용법도 간단하지만 가끔 어떤 식으로 주석을 해야하는지 까먹습니다. 
아래와 같은 형식이 가장 마음에 들고 좋은 것 같습니다.

\brief 나 \return 등이 보여주는 항목 이외에 다른 항목을 쓰고 싶다면 \par 명령어를 사용하면 된다.

/** \brief

        현재 시간을 얻는다.

    \remarks

        ST_TIME 구조체 형식으로 현재 시간을 얻는다.

    \par 요구사항

        time.h 선언이 필요하다.

    \return

        성공시 0을 반환한다. 에러가 발생하면 -1을 반환한다.

    \author

        이상호

**/




Blogger: moltak.net 

'Programming > 이것저것' 카테고리의 다른 글

[펌] valgrind 를 이용한 메모리 관리  (0) 2011.03.15
Doxygen - 작성중  (0) 2011.03.08
_Crt Debug Functions  (0) 2010.07.23
typeid 2  (1) 2010.05.25
세그먼트 레지스터  (0) 2010.05.01

메모리 릭을 해결하기 위해 문서를 찾던중
[펌: http://adnoctum.tistory.com/555]


   C/C++ 의 골치거리 중 하나인 메모리 문제를 조금이나마 쉽게 해결하고자 나와 있는 프로그램 중 사용이 편리하고 open-source 인 valgrind 에 대해 알아 보자. valgrid는 leak 이 생긴/생길 가능성이 있는 코드의 부분을 찾아 주고, 잘못된 메모리 접근을 알려 주는 등의 기능을 한다. 이것은 특히 다른 사람이 작성한 소스 코드를 이용해야 할 때 유용한데, 코드의 전체적인 내용을 파악하지 못한 상태에서도 메모리 검사를 할 수 있기 때문이다. 나의 경우도 지금 남의 코드를 가져 와서 하고 있기 때문에, 일단 실행 시간 에러는 없이 실행되는 것을 확인했지만 정말로 문제없이 돌아가는 것인지 확인하기 위해 오랜만에 valgrind를 꺼내 들었다. 실제 사용 예는 다음과 같다. 

[adnoctum@bioism src]$ g++ ~/LJSLibrary/library/util.o cluster.o cluster.cpp -o c -g
[adnoctum@bioism src]$ valgrind --leak-check=full --log-file-exactly=memcheck.txt -v --error-limit=no ./c test.txt

첫 번째 줄은 test 로 사용할 프로그램을 컴파일 하는 부분. -g 옵션을 줘야 함수 이름과 정확한 코드의 위치(줄 수)가 나와서 보기 쉽다. valgrind 의 option 은 적당히 준다. valgrind --help 에 잘 나와 있다. 사용법은 아주 간단하다. 

valgrind [options] executible

을 따른다. option 은 적당히 주면 되고, executible 은 원래 프로그램을 실행시키는 것과 같다. 즉, 위의 경우 실행 파일이 c 이고 입력으로 test.txt 파일을 넣게 되어 있다. 그래서 이 프로그램을 실행시키려면 원래는

./c test.txt

를 하게 되는데, 바로 이 부분을 valgrind 의 입력으로 넣으면 되는 것이다. 그래서 위의 예에서 2 번째 줄처럼 된다. 

-v 옵션을 주면 내용이 많기 때문에 좀 복잡할 수 있는데, 차근차근 따라가면 별로 어렵지 않다. 결과 파일이 매우 길기 때문에 부분부분 가져와서 왜 문제가 생겼는지를 소스 코드와 비교해 보자. 

일단 가장 아래부분 근처에 보면 다음과 같은 요약이 있다. 

==9581== IN SUMMARY: 9 errors from 9 contexts (suppressed: 15 from 1)
==9581==
==9581== malloc/free: in use at exit: 0 bytes in 0 blocks.
==9581== malloc/free: 4,997 allocs, 4,997 frees, 243,658 bytes allocated.
==9581==
==9581== All heap blocks were freed -- no leaks are possible.

일단 메모리 누수는 없는 것으로 보인다. 제일 앞에 쓰여 있는 숫자는 PID 이다. 만약 --PID-- 이면 정보를 보여 주는 것이고, 만약 == PID == 라면 에러가 난 부분을 보여 주는 것으므로 참고한다. 그럼 이젠 제일 앞부분부터 살펴 보자. 

==9581== Invalid read of size 8
==9581==    at 0x805DC0F: main (cluster.cpp:149)
==9581==  Address 0x4096238 is 8 bytes after a block of size 224 alloc'd
==9581==    at 0x40053C0: malloc (vg_replace_malloc.c:149)
==9581==    by 0x805B067: treecluster (cluster.c:3656)
==9581==    by 0x805DB52: main (cluster.cpp:134)

내용인 즉, 8 바이트를 읽었는데, 원래는 읽으면 안되는 것이었다는 것이다. 직접적인 줄은 cluster.cpp 파일의 149 번째 줄이고, 밑에 call stack 이 나와 있다. 그래서, cluster.cpp 파일의 149 번째 줄 근처로 가보면, 


134   Node* tree = treecluster(nRow, nCol, data, mask, weight, transpose, metric, method, NULL);
135
136   int nNodes = 0;
137   if(transpose != 0){
138           nNodes = nCol;
139   }
140   else{
141           nNodes = nRow;
142   }
143   double* order = (transpose==0) ? new double[nCol] : new double[nRow];
144   for(i = 0; i<nNodes; i++) order[i] = i;
145   if (metric=='e' || metric=='b')
146   /* Scale all distances such that they are between 0 and 1 */
147   { double scale = 0.0;
148     for (i = 0; i < nNodes; i++)
149       if (tree[i].distance > scale) scale = tree[i].distance;
150     if (scale) for (i = 0; i < nNodes; i++) tree[i].distance /= scale;
151   }

위 코드인데, 149번째 줄에서는 tree를 접근하고 있다. 위에서 8 바이트라 했으므로, 아마도 double 형 요소인 distance 를 말하는 것일테고, 위 코드와 잘 맞는다. 그럼 왜 읽지 말아야 하는 부분을 읽었다고 했을까? 조건(148라인)을 보면 for 문에서 i 를 nNodes 까지 돌리고 있다. 즉, nNodes-1번까지 돌테고, 일반적으로 잘 맞는듯이 보인다. 그런데, 134 번째 줄을 보니 tree 는 treecluster 라는 함수의 반환값이고, nNodes 는 137번째 줄에서 적당히 설정되고 있다. 이 부분은 좀 이 예 의존적이긴 한데, 어쨌든 어떻게 풀어 나가는지에 대한 흐름만 따라가 보자. 위 코드는 Cluster 3.0 의 소스 코드를 가져 온 것인데, 메뉴얼에 보면 hierarchial clustering 결과 반환되는 노드 수는 원래의 item 보다 한 개 적다고 한다. 즉, 지금 nCol을 기준으로 clustering 을 하면 반환되는 노드 수는 nCol - 1 이어야 하는 것이다. 따라서 tree의 index 는 nCol - 2 까지만 가야 하겠지. 따라서 위의 코드 중에는 138, 141 번에서 - 1 을 추가해 주어야 한다. 이런 에러는 중요하다. 왜냐 하면, 이렇게 읽지 말아야 하는 곳을 읽을 경우 에러가 났다 안났다 하기 때문에 잡기 좀 어렵기 때문이다. 매번 죽으면 상관이 없는데, 같은 release mode라 해도 어떤 때는 잘 되고 어떤 때는 죽는 경우는 디버깅 하기 참 어려운데, 이렇게 접근하면 안되는 곳을 접근하는 경우 자주 그렇게 된다. 언뜻 봐선 에러 없이 끝난 것 같아도 실은 언제 터질지 모르는 고장난 시한 폭탄을 갖고 있는 격. 결국, 데모할 때 터지겠지, >.<"" 어쨌든, 이 부분은 이렇게 해결하고, 다음으로 넘어 가면, 

==9649== Mismatched free() / delete / delete []
==9649==    at 0x4004973: operator delete[](void*) (vg_replace_malloc.c:256)
==9649==    by 0x805E268: main (cluster.cpp:235)
==9649==  Address 0x4096E98 is 0 bytes inside a block of size 120 alloc'd
==9649==    at 0x40046FF: calloc (vg_replace_malloc.c:279)
==9649==    by 0x805D164: TreeSort(char, int, double const*, double const*, int const*, Node*, double**) (cluster.cpp:25)
==9649==    by 0x805DFF9: main (cluster.cpp:215)

malloc/free, new/delete, new []/delete [], 에 대한 대응이 잘못되었다는 얘기다. 실제로 235번째 줄은 delete [] neworder; 로 되어 있는데, 소스 코드를 보면 neworder 는 calloc 으로 할당이 된다. 따라서 이 부분에 맞게 free로 바꿔 주면 문제 해결. 원래의 코드가 ANSI  C 로 되어 있고 난 C++을 써버릇해서 이런 문제가 생겼다. 

   초기화되지 않은 변수에 의존해서 jmp 나 move, 즉 if 문 안쪽에 초기화되지 않은 변수에 의해 비교, 할당이 일어날 수 있다는 경고도 있는데 그것은 생략한다. 

'Programming > 이것저것' 카테고리의 다른 글

Doxgen 주석  (0) 2011.05.02
Doxygen - 작성중  (0) 2011.03.08
_Crt Debug Functions  (0) 2010.07.23
typeid 2  (1) 2010.05.25
세그먼트 레지스터  (0) 2010.05.01
1.파일

/**

@file main.cpp

@date 2009/04/25

@author 홍길동(hong@aaa.com)

@brief 프로그램의 구동

*/

 

2.클래스

해당 클래스 선언부 위에 위치한다.

/**

@class main.cpp

@date 2009/04/25

@author 홍길동(hong@aaa.com)

@brief 프로그램의 구동

@warning 주의 사항이 있으면 이 곳에 입력한다.

*/

 

3.함수 설명

해당 함수 위에 위치한다.

/**

@return char * : 이름

@param strPersonNum : 주민등록번호

@brief 해당 주민등록번호의 이름을 가져온다

@warning 주민등록번호는 - 없이 입력한다.

*/

 

4. 간략설명

 해당 라인의 뒤에 위치한다.

unsigned logn nAssetIP;     ///< 자산 아이피

또는

unsigned logn nAssetIP;     /**< 자산 아이피 */

 

5.주석 내 사용되는 item 들

 @breif        간략한 설명을 쓴다.
 @remarks   자세한 설명을 쓴다.
 @file          파일 이름을 구별할때.
 @return      함수의 리턴값 나타낼때.
 @author     작성자 이름을 나타낼때
 @date        작성날짜를 나타낼때.
 @param      함수 파라메터를 나타낼때
 @see         참고할 함수나 페이지를 지정한다.
 @todo        해야할일들에 대한 기술, 전체 항목의 @todo에 대한 리스트가 생성됩니다
 @bug         버그에 대한 기술, 전체 항목의 @bug에 대해서 따로 리스트가 생성됩니다.
 @code       중요 코드를 설명할때 시작 지점 가리킨다.
 @endcode  중요 코드 설명할때 종료 지점 가리킨다.
 @exeception exception처리에 대한 설명
 @mainpage
 @section


 @throw: throw하는 객체나 변수등에 대한 설명

'Programming > 이것저것' 카테고리의 다른 글

Doxgen 주석  (0) 2011.05.02
[펌] valgrind 를 이용한 메모리 관리  (0) 2011.03.15
_Crt Debug Functions  (0) 2010.07.23
typeid 2  (1) 2010.05.25
세그먼트 레지스터  (0) 2010.05.01
안녕하세요. moltak 입니다.


메인 OS를 리눅스로 바꾼게 1주일 쯤 됐네요.
불편한 것은 거의 없었고. 아주 빠르고 쾌적한 환경에 매우 만족 중입니다.

다만... MS Office를 제대로 사용할 수 없다는 점이 좀 걸리긴 했었습니다.
(Wine으로 사용하는 MS Office는 반쪽 자리더군요. 기능이 잘 안되는....)
그래서 Virtual Box에 윈도우7을 깔아서 MS Office를 이용했습니다.
하지만 너무도 느린 속도 탓에(도대체 왜 이렇게 느린건지)
엄청난 메모리 사용량...(Win7 구동전 15% 구동후 90%)
그래서 가상화 프로그램과 OS를 바꾸기로 했습니다.

가장 많이 사용하는 가상화 프로그램 VMWare와 WindowsXP sp3으로 바꿨습니다.
WindowsXP를 사용 중인데 메모리는 24%정도 되네요.
그리고 MS Office도 훨씬 쾌적한 속도로 이용할 수 있습니다.




우분투에서 VMWare 설치법이 잘 나와있지 않았습니다. 
(검색해보면 VMWare에서 우분투 설치하기만 나오더군요.)

그래서 직접 부딪혔습니다.
검색 할 시간에 차라리 진작 해봤으면 됐을 껄 이라는 생각이 들더군요.
아주 쉬웠습니다.


VMWare Linux 로 검색을 해서 설치 파일을 받으시구요.
(전 토xx 를 이용...ㅋㅋㅋ)
chmod 777 주신 후에 그냥 설치하시면 끝납니다.
VMWare의 Unity 모드도 사용가능 합니다. 좋습니다. ㅋㅋ

궁금한 점들은 메일 주세요~~ㅋㅋ



Bloger : moltak.net
안녕하세요. molatk 입니다.

이번에 전 겨울 맞이로 해서....
그 좋은 윈도우를 버리고 리눅스로 완전 갈아 탔습니다. ㅋㅋ
메인 컴퓨터를 싹 밀고 우분투를 설치했습니다.
많이 사용해보지 않아서 무서웠지만....
좋은 툴이 굉장히 많더군요.!!

웹브라우저는 물론이고 개발 도구도 전혀 부족함이 없습니다.!!
(사실 개발 도구는 Visual Studio 진영이 너무 강력해서.... 부족합니다. ㅋㅋ)



툴 설명을 먼저 해드리겠습니다.
개발툴: Qt Creator
버전관리: RabbitVCS
Office: MS Office 2007(Wine으로 구동 중), Open Office(잠깐 써봤는데 좋습니다. 편해요ㅋㅋ)
웹브라우저: Chrome 
Design Tool: Visual Paradigm UML Community Edition
Messager: NateOn
그 밖에 Thunderbird, VirtualBox 등등 설치해서 사용 중입니다.

저 많은 프로그램을 띄워 놓고도 메모리는 26%밖에 사용하지 않네요.
3Gbyte * 26% = 780Mbyte 밖에
속도는 무지 빠르고ㅋㅋ

다른분들도 우분투에 도전해 보세요. ㅋㅋ
(근데 Word에서 원격 블로깅이 안됩니다. ㅠㅠ 더 찾아 봐야 할 듯.)



Bloger: moltak.net
Qt Creator 에서 외부 라이브러리를 사용하려면 옵션을 좀 설정해줘야 하는 군요.
좀 해멨습니다.

이번 블로깅의 목표는
Qt Creator를 이용해 프로젝트를 추가하고 gtest를 이용해 보자 입니다.

순서는 대략 아래와 같습니다.
1) Qt Creator 실행(설치는 이미 되어있다고 생각하겠습니다.)
2) 프로젝트 생성
3) 코딩
4) 프로젝트 파일 수정
5) 컴파일 & 링크
6) 실행


4)번을 보시면 아시겠지만. Qt Creator는 QMake를 사용하기 때문에 옵션을 조금 바꿔 줘야 합니다. 그것을 4)번에서 바꾸게 됩니다.


1) Qt Creator 실행, 프로젝트 생성 
(반드시 Qt Creator와 gtest가 설치되어 있어야합니다.)
Qt Creator를 실행하셔서 프로젝트를 생성합니다.

프로젝트 생성


이름은 마음데로 하시구요


저는 Qt Console Application을 선택했습니다.


프로젝트를 생성하실 때 Qt용 Console 프로젝트로 생성하시면 됩니다.

3) 코딩
위의 코드를 아래와 같이 변형해주세요.
코드를 보시면 아시겠지만 아주 간단한 코드 입니다.
다만 gtest를 사용하기 위해서 하나의 TEST를 추가해 주었습니다.

#include <iostream>
using namespace std;
#include <gtest/gtest.h>
TEST( test, test )
{
    EXPECT_EQ( 1, 1 );
}
int main(int argc, char *argv[])
{
    ::testing::InitGoogleTest( &argc, argv );
    RUN_ALL_TESTS();
    cout << "test" << endl;
    return 0;
}

4) 프로젝트 파일 수정
자 여기가 제가 제일 헤멘 곳인데요.
프로젝트 탭에 보시면 프로젝트명.pro 파일이 보이실 겁니다.
그것을 열어서 아래 한 줄을 추가해 주세요.

LIBS += "/usr/local/lib/libgtest.a" 를 추가해주세요.


LIBS += "/usr/local/lib/libgtest.a"

gtest는 ./configure && make && make install 하면 한번에 설치가 끝나고, 컴파일때 생성된 파일들은 /usr/local/lib 에 생성됩니다. 그래서 위와 같이 라이브러리 파일을 링크해주시는 겁니다.


5) 컴파일 & 링크 & 실행

테스트 통과 화면 && "test" 출력 화면


자 끝났습니다.


이상으로 Qt Creator에서 gtest를 사용하는 것을 해봤습니다.

저는 리눅스를 거의 처음 사용해보기 때문에 고수님들이 보시기에는 매우 쉬운 것들도 굉장히 헤매게 되네요.

그럼 이만 물러가겠습니다.




Bloger: moltak.net

이 글은 개인적인 경험을 바탕으로한 해결책들이다.
100% 신뢰할수는 없으나, 적어도 나는 효과본 방법임을 미리 밝혀둔다.

본인은 단위테스트 도구로 c++unit을 쓰다, unittest++이 더 편한거 같아서 그쪽으로 옮겨갓다가
잠시 boost쪽도 써봣다.


문제는 다들 하나씩 문제가 있거나 뭔가 불편하다는 거엿다.
예를들어 c++unit과 boost는 테스트하기 위해 생산하고 관리할 코드가 산더미가 될수도 있었고
unittest++은 내가 몰라서 그런진 몰라도 테스트하기 껄끄러운 테스트케이스들이 있어서 좀 난감햇다.

하지만 어찌됫건 사용하기 편한건 unittest++이라 그쪽으로 계속 사용했는데...

최근 리눅스로 옮겨타서 뭔가 만들일이 있어서 netbeans를 쓰다 여기서 c++unit이 지원된다는걸 발견!
자동으로 코드도 만들어주니 잘 써먹으려 했으나 역시 몇가지 짜증나는 문제들이 있어서 안쓰기로 결정했다.

그러다 눈에 띈게 google test였는데...

이것도 사용하기 간편한 쉬운 단위 테스트 라이브러리라 일단 설치하고 쓰다보니 이거말고 다른걸 못쓰겟더라;;
(일단 능력 자체는 unittest++과 비슷한데, 더 쉽다. 쉽고 간단하다는게 아주 크다.)


어찌됫건 gtest를 쓰려다/쓰다 생기는 몇가지 문제를 해결하기 위한 트릭을 몇개 적어볼까 한다.



1.설치
일단 설치부터 난관인데...
우분투나 오픈수세같은 플랫폼의 gcc라면 그냥 아무런 생각도 하지 말고 

#./configure
#make
#make install

하면 된다.

설치위치는 /usr/local/ 이며, 라이브러리는 lib, 헤더는 include에 들어가 있다.

icc도 크게 다를건 없을꺼다.



2.컴파일이 안되요, 링커가 앙탈부려요
당연한 이야기지만 프로젝트 설정 같은데 보면 include설정하고 lib설정 있을 거다.
그걸로 설정하면 
헤더를 못찾겠는데요?, 라이브러리는 어딧나요?
같은 이야기는 대부분 사라진다.

넷빈의 경우 프로젝트 설정의 컴파일러 부분에 있는 include dir 부분과 링커의 librareies 부분을 만져주면 된다.
만약 full path 입력이 귀찮다면 환경변수 부분에 설정해 두고 입력하면 된다.

문제는 다음에서 발생한다.



3. undefined reference to `pthread_key_create' ..... 라는 형태로 링커 에러가 뜬다.
이거 아주 간단하게 해결된다.
gtest는 스레드 기반인듯한데...
당연하게도 -lpthread 를 붙여줘야 한다.

본인은 openmp 쓰느라 모르다가 어쩌다 딴거 테스트하다 본 에러라 쉽게 해결했다.


넷빈의 경우 프로젝트 설정의 링커 부분에 libraries 부분이 있는데 거기 들어가서 옵션 눌어 추가해주면 된다.


4. 실행파일이 libgtest.so.0 을 못찾겟단다
이거 의외로 해결하기 골치아프다.

실행파일을 ldd로 찍어보면 not found 찍히는데
/usr/local/lib 가면 libgtest.so.0 이녀석은 멀쩡하게 존제하고 잘 작동중이다.

왜이럴까?

결국 임시방편으로 ld_library_path로 쇼부치다(내가 리눅스를 아는 수준은 딱 이정도가 한계다;;) 

검색으로 다음과 같은 포스트를 찾아냇다.
http://www.openguru.org/2009/04/how-to-fix-shared-library-load-problem.html

맨 아래 보면 ldconfig를 만저서 해당 문제를 멋지게 해결해내고 있다.

저게 옳은 방법인지는 확실치 않지만, 어찌됫건 해결되면 장땡.



이로서 gtest준비는 끗~

이제 주 프로젝트와 여러개의 테스트 프로젝트를 굴리면서 프로그래밍을 하면 된다.
이미 정의되어 있습니다. 무시
/FORCE:MULTIPLE


Bloger : moltak.net

안녕하세요. moltak 입니다.

윈도우에서 Eclipse로 개발하면 컴파일러를 gcc를 사용하게 됩니다.

 

 

Eclipse에 CDT를 설치해서 소스코드 작성하고 gcc를 이용해 컴파일하며 gdb를 이용해 디버깅 하게 됩니다. 리눅스에서는 아주 쉽게 되는 작업이지만 처음 사용하는 저는 굉장히 어려웠습니다.

 

 

이 포스팅의 목표는 GoogleTest(이하 gtest)를 윈도우에서 gcc를 이용해 컴파일하고 eclipse에서 사용하는 것을 목표로 하겠습니다. 먼저 Eclipse와 JDK, CDT가 없으신 분은 [Eclipse에서 C, C++ 개발환경 구축하기] 를 참고하셔서 먼저 설치를 하시기 바랍니다.

 

 

먼저 gtest를 다운로드 받습니다. http://code.google.com/p/googletest/downloads/detail?name=gtest-1.5.0.zip

그 후 압축을 푼 후 아래를 따라 합니다.

실행 -> cmd -> cd gtest directory -> cd make -> mingw32-make Makefile all -> mingw32-make gtest.a

Figure 1 MinGW32-make

 

 

Figure 2 Make 수행 후

제대로 되셨다면 gtest.a 가 생성이 됩니다. .lib 라이브러리 파일은 msvc에서만 사용하는 라이브러리 파일이고 gcc는 .a라는 라이브러리 파일을 사용하게 됩니다. gtest.a 가 제대로 생성이 됐다면 이제 gtest를 사용하는 일만 남았습니다.

 

 

Figure 3 GTest 예제 코드

 

위 코드는 gtest를 사용하는 예제 코드입니다. 이 코드를 돌려 보도록 하겠습니다.

Eclipse를 실행시켜주세요. C++ 프로젝트를 생성 하신 후 위 코드를 작성 합니다.

이제 이클립스에서 몇 가지 설정을 해줘야 하는데요.

 

프로젝트 속성 -> C/C++ Build -> Settings -> GCC C++ Compiler -> Directories 부분에 gtest\include 폴더 추가해 주세요.

 

그리고 제가 가장 헤멘 부분. [.a] 링크하기!! 처음에 .a파일을 생성해야 하는 이유도 몰랐고 어떻게 하는지도 몰랐죠. 몇 일간 헤메니깐 답이 보이더군요. (이클립스를 이용해서 윈도우 플랫폼에서 C++ 개발하는 분들이 별로 없나 봅니다. 검색해도 잘 나오지 않던…)

 

다시 프로젝트 속성에 가셔서 C/C++ Build -> Settings -> MinGW C++ Linker -> Miscellaneous -> Other objects에 [gtest.a] 파일의 경로를 지정해 주시면 됩니다. 그리고 컴파일 하시면 성공!!

 

Figure 4 실행 화면

Figure4 그림처럼 나오면 성공입니다. ^^

 

 

이 글을 작성하고 나니깐 지난 3일간이 제가 엄청나게 삽질을 했다는 것을 알겠네요. 블로깅 양이 엄청 적은… 하지만 이제 리눅스와 윈도우에서 똑 같은 개발 환경을 갖고 프로젝트를 진행 할 수 있다는 것이 너무나 기쁘네요.

 

GTest를 G++로 컴파일해서 eclipse로 컴파일해서 사용했다는 것은 이제 어떤 라이브러리도 사용할 수 있다는 것을 뜻합니다. 물론 좀 복잡하게 사용해야 하지만… MSVC가 너무 잘 만들어진 IDE라서 윈도우에서는 MSVC 말고는 사용하기 힘들기도 할 것 같습니다. 하지만 Eclipse의 매력도 얕볼 수가 없는데 리눅스에서도 똑 같은 자신의 환경을 갖고 프로그래밍 할 수 있다는 큰 매력이 있다는 것입니다.

 

 

 

Bloger : moltak.net

이클립스에서 C, C++을 개발 환경을 구축하기 위한 글입니다.
아주 상세히 정리를 해 놓으셨네요.

이 글은 http://blog.jidolstar.com/677 에서 첨부해왔습니다.


윈도우 환경에서 Eclipse Galileo 버전으로 C, C++ 개발을 위한 환경을 만드는 것을 설명하는데 목표가 있다. 기존에 Eclipse기반으로 Flash Builder 플러그인을 설치해 Flash 개발을 하거나 Java 개발하시는 분들이 같은 환경에서 C, C++을 개발하고자 한다면 이 글은 유용한 팁정도가 될 것이다.


1. MinGW를 설치한다. 
MinGW(한국어 발음 밍우?)는 무료로 쓰고 배포할 수 있는 MS 윈도우 헤더 파일과 라이브러리로, 어떠한 써드 파티 C 런타임 DLL에 의존하지 않고 네이티브 윈도우 프로그램을 만들 수 있는 GNU 툴을 제공한다. 쉽게 이야기해 MinGW는 윈도우에서 툴이나 dll에 의존하지 않는 동작하는 프로그램을 만들 수 있도록 도와준다.

MinGW에 대해 : http://ko.wikipedia.org/wiki/MinGW 

물론 C/C++를 개발하기 위해 Cygwin을 이용해도 된다. 하지만 cygwin 기반으로 제작한 것은 항상 cygwin1.dll이 필요한다. 또한 개발한 결과물은 라이센스 문제로 상용으로 팔기가 곤란하다. 게다가 윈도우에서 직접 개발한다기 보다 가상의 리눅스 콘솔을 이용하는 것이다. 그래서 여러가지로 MinGW이 장점이 많다.


1.1 MinGW 받기 
공식 사이트 http://www.mingw.org/ 로 간다. 좌측 메뉴에 Downloads 페이지로 이동한다. Download Now 버튼을 눌러 최신버전인 MinGW-5.1.6.exe(2010.04.20)를 다운로드 받는다. 


1.2 MinGW 설치
  • 다운받은 MinGW-5.1.6.exe를 실행한다.
  • Welcome 화면 Next를 클릭한다.
  • Download and install을 선택후 Next 버튼을 클릭한다.
  • I agree를 클릭한다.
  • Candidate를 선택후 Next를 클릭한다.
  • 설치하고자 하는 것을 선택후 Next를 클릭한다. g++ compiler와 MinGW Make는 반드시 선택한다.
  • 설치하고자 하는 디렉토를 선택한 다음 Next 클릭
  • Install을 클릭하면 이제 필요한 것을 다운로드 받아 설치를 시작한다.
  • 설치가 완료되면 Next 클릭후 Finish를 누른다.

 

1.3 GCC를 실행하기 위한 윈도우 환경변수 설정하기

이제 어느 경로에 있던지 gcc 컴파일러를 실행할 수 있도록 환경을 조성해줄 필요가 있다. 

이 방법은 Cygwin을 사용하지 않고 오로지 MinGW만 사용하는 경우에 해당한다. 만약 Cygwin을 함께 사용하시는 분이라면 배치파일을 만들어 사용하는 방법도 있다. (http://kldp.org/node/48962)

  • 제어판에서 시스템 폴더 클릭. window 7환경에서 개발한다면 검색창에서 시스템을 입력한뒤 시스템 환경 변수 편집을 선택한다.
  • 아래 표시된 방법대로 입력하면 되겠다. 최종적으로 MinGW 설치된 폴더에 Bin 폴더를 입력하는 것을 목표로 한다.


  • CMD창에서 gcc --version과 mingw32-make를 입력하고 다음과 같이 나오면 성공적으로 설치된것임

 이제 MinGW가 설치되었으므로 window 기반에서 C, C++등을 개발할 수 있는 환경이 만들어진 것이다. 다음에 나오는 Eclipse기반이 아니더라도 메모장에서 C코드를 짜고 GCC로 컴파일할 수 있다. 하지만 개발툴을 메모장을 사용할 수는 없는 노릇아닌가?


2. Eclipse Galileo 버전을 설치한다.
Eclipse는 기존에 설치했던 사람이 대부분일 것이다. 이 설명은 필요없는 내용일 수 있으나 그냥 적어본다.

일단 Eclipse는 아래 링크에서 자신의 개발하고자 하는 목적별(Java, C/C++, PHP등)로 다운로드 받아 설치할 수 있다. 

http://www.eclipse.org/downloads/

필자는 Java기반에서 개발하는 일이 많으므로 Java EE Developers를 위한 Eclipse IDE를 설치했다. Windows 32bit 기반을 다운로드 받았다. 설치는 받은 압축파일을 원하는 곳에 압축만 풀어주는 것으로 완료가 된다. 본인은 E:\eclipse 에 설치했다. C 드라이브에 설치하지 않은 이유는 나중에 운영체제를 다시 설치하는 경우에 Eclipse를 보존하기 위함이다.

Eclipse를 처음 설치하는 사람이라면 반드시 JRE가 자신의 컴퓨터에 미리 설치가 되어 있어야 Eclipse 구동이 가능하다. 다음 링크에서 JRE나 JDK 최신버전을 설치하면 되겠다.

http://java.sun.com/javase/downloads/index.jsp

만약 C/C++기반인 Eclipse를 다운로드 받아 설치하면 다음에 "3. CDT 플러그인을 설치한다"를 넘겨도 된다. 


3. CDT 플러그 인을 설치한다.

CDT는 C/C++ Development Tool이다. 기존에 이클립스 기반으로 개발하던 사람이라면 C/C++도 Visual Studio와 같은 툴을 활용하지 않고 개발하고자 하는 욕구(?)가 들지도 모르겠다. CDT를 Eclipse에 설치하면 C,C++ 개발이 가능한 환경이 된다. 

CDT는 개발하는 툴이지 컴파일러가 아니다. CDT를 설치했더라도 각각 운영체제 기반에서 제공하는 C/C++ 컴파일러와 연결하는 작업은 필요하다. 여기서는 CDT를 Eclipse에 설치하는 방법만 소개한다.

Eclipse 메뉴에서 Help > Install New Software... 를 선택한다.

아래와 같은 화면이 나오면 Add 버튼을 누른다.


http://www.eclipse.org/cdt/downloads.php 에 가면 최신버전(현재 CDT 6.0.x)을 다운로드 받을 수 있는 링크가 소개되어 있다. Eclipse가 Galileo버전이므로 http://download.eclipse.org/tools/cdt/releases/galileo 를 URL로 삼아 플러그인을 설치하면 되겠다. 

아래처럼 Add Site창에 Name과 Location을 입력한다. Name은 아무거나 입력하면 된다.


참고로 위처럼 등록하면 Windews > Preferences > Install/Update > Avaliable Software Sites에 아래처럼 등록되어 있다. 


이제 Work with 란에 CDT를 입력해보면 금방 등록했던 CDT 정보를 선택할 수 있다. 그럼 아래처럼 나온다. CDT Main Features, CDT Optional Features 모두 Check하고 Next버튼을 누른다.


아래처럼 설치할 목록들이 나온다. Next버튼을 누른다.



아래와 같은 화면이 나오면 I accept the terms of the license agreements를 선택후 Finish 버튼을 누르면 설를 시작한다. 시작이 완료된 다음에는 Eclipse를 재구동한다. 



Eclipse가 구동된 다음 C/C++ Perspective를 열어보자. Windows>Open Perspective>Other 를 선택한다. 아래처럼 창이 뜨면 C/C++를 선택한다. 
 

Perspective창에 아래처럼 추가 된것을 확인하자. 이제 Eclipse에서 

File > New를 가도 C, C++ 프로젝트를 만들 수 있게 되었다. 


4. 간단한 C/C++ 개발해보기

MinGW의 bin 폴더에 보면 gcc, g++등 각종 컴파일 도구가 있다. 이클립스의 CDT환경에서 C/C++로 개발할때는 MinGW의 컴파일 도구를 이용해 컴파일 한다는 사실을 기억하자.

다음과 같이 C++ 프로젝트를 만들어보자. 
  • 이클립스 메뉴에서 File > New > C++ Project를 선택한다.
  • 다음 그림과 같이 프로젝트를 만들기 위한 창이 나오면 Project name을 넣고 Project type을 Executable > Hello World C++ Project를 선택한다음 Toolchains를 MinGW GCC로 선택하도록 한다. 이렇게 하면 자동으로 Hello World CPP가 만들어지면서 컴파일은 MinGW의 g++컴파일러를 이용해 컴파일 할 수 있도록 설정 되는 것이다. Next 버튼을 누른다.
  • 간단한 셋팅을 하는데 이 설정에서 중요한 것은 Source 파일은 src 폴더에 들어가게 된다는 것이다. Next 버튼을 누른다.


  • 다음 그림과 같이 Debug, Release 두 버전으로 프로그램 결과를 별 수 있도록 셋팅된다. Finish 버튼을 누른다. 

 

이클립스의 Project > Build Automatically가 선택되어 있다면 위처럼 프로젝트를 만들게 되면 자동으로 MinGW의 g++을 찾아 컴파일을 실시하게 된다. 아래와 같은 메시지가 이클립스의 Console창에 나오면 제대로 실행된 것이다. 


위 메시지 처럼 컴파일을 하지 못하고  아래처럼 Nothing to build for Test1 메시지가 뜬다면 이것은 수정된 내용이 없으므로 컴파일할 필요가 없다는 것을 의미한다. 대신 Ctrl+B 하면 강제로 컴파일한다.


이 프로젝트는 C++ 프로젝트이므로 gcc 컴파일러가 연결되어야 한다. 만약 컴파일에 실패한다면 Mingw/bin에 gcc.exe를 확인해보자. 만약에 없다면 위에 Mingw 설치하기를 다시 한번 따라해보길 바란다.

실행해보자. 아래처럼 만들어진 프로젝트의 src폴더를 열어 Test1.cpp를 선택한다. 그리고 빨간 박스로 표시된 아이콘을 클릭하거나 Ctrl+F11을 하면 실행할 수 있다.

Console창에 아래처럼 Hello World가 출력된것을 확인하자.

Build Automatically를 체크한 경우에는 코드를 수정하고 저장할 때마다 자동 Build처리된다. 하지만 수동으로도 할 수 있는데 Ctrl+B 또는 아래 그림처럼 망치툴을 클릭해서 Build할 수 있다.



개발시에는 Debug버전과 Release 버전이 있다는 것을 기억하자. 아래 보이는 도구는 현재 개발 환경이 Debug인지 Release인지 결정해 주는 도구이다. Debug는 개발용이고 Release는 외부로 배포할때 사용한다.


실제로 이 도구를 이용해 Debug에서 Release로 바꿔보자. 아래처럼 Release 폴더가 생겨나고 컴파일 결과가 이 폴더안에 만들어진다. 이때부터는 실행할때 Release폴더에 있는 exe파일이 실행되게 된다.


참고로 makefile을 기반으로한 개발을 하고 싶은 경우가 있을 수 있다. 이런 경우에는 C++ 프로젝트를 생성시에 아래 그림처럼 Makefile Project를 선택해서 생성해야한다. 

하지만 실제로 이 상태로 프로젝트를 생성해 컴파일하면 Cannot run program "make": Launching failed 메시지가 console창에 보이면서 컴파일이 불가능하다. 이 메시지는 컴파일을 수행할 수 있는 make 명령어를 찾지 못한다는 것을 의미한다. Eclipse에서는 기본적으로 make가 지정되어 있지만 MinGW의 make 명령은 mingw32-make로 다르다. 그러므로 이 문제를 해결하기 위해 mingw32-make.exe를 복사해 같은 폴더에 make.exe로 이름을 바꿔주면 된다. (물론 찾아보면 다른 방법도 있지만 이 방법이 가장 빠르고 쉽다.) 

makefile을 이용해 개발해보는 간단한 예제는 다음글을 참고한다.
http://kkamagui.springnote.com/pages/446531


5. 간단한 win32용 프로그램 개발하기 
지금까지의 예제는 단순히 Console창에 결과가 나온다. MinGW는 Windows API를 이용한 개발도 지원하므로 앞서 설명한 같은 C++ 프로젝트로 만들고 아래 코드로 변경해도 컴파일이 가능하다.


01.#include <windows.h><windows.h>
02. 
03.int WinMain(HINSTANCE hInstance,
04.HINSTANCE hPrevInstance,
05.LPTSTR    lpCmdLine,
06.int       nCmdShow)
07.{
08.MessageBox(NULL, "Hello in EclipseCDT""EclipseCDT", MB_OK);
09.return 0;
10.}
11.</windows.h>


실행해 보면 아래와 같은 다이얼로그 창이 나온다.

경험자들에 따르면 Win32 로 개발하는 경우에는 한가지 중요한 C++ 링커 설정을 해야한다고 한다. 

먼저 해당 Win32 프로젝트를 선택후(필자의 경우 Test3) 이클립스 메뉴에서 Project > Properies로 들어갑니다. 아래처럼 창이 뜨면 C/C++ Build > Setting으로 들어가 Tool Setting 탭을 선택합니다. 거기에 MinGW C++ Linker>Miscellaneous를 선택해 Linker flags에 -mwindows를 입력한다. 완료하면 Apply버튼이나 OK 버튼을 누르면 적용된다.

이 설정을 해야 군데 군데 "undefined reference"와 같은 에러를 발생시키지 않는다고 한다. 수정했는데도 에러를 띄우면 File->Save all 또는 이클립스 종료후 다시 시작하면 된다. 

Windows API 학습을 위해 다음 링크를 참고한다.
http://www.winapi.co.kr/

6. 디버깅 환경 만들기
지금까지 개발환경으로 개발자체는 문제 없지만 디버깅은 할 수 없다. MinGW에 디버깅을 하기 위한 도구가 설치되어야 하는데 이를 가능하게 하는 것이 gdb이다. 

먼저 gdb를 다운로드 받자.
http://downloads.sourceforge.net/project/mingw/GNU%20Source-Level%20Debugger/GDB-7.1/gdb-7.1-2-mingw32-bin.tar.gz 

압축을 풀고 bin과 share 폴더를 그대로 설치된 MinGW 폴더에 복사해준다. 이것으로 MinGW의 C/C++ 디버깅 환경이 구축되었다.

이제 Eclipse에서 F11 누르거나 아래처럼 벌레모양의 아이콘을 눌러 Debugging을 할 수 있게 된다.


디버깅을 하게 되면 Debug Perspective창으로 바뀌면서 아래처럼 디버깅이 가능해진다.

참고로, 이클립스에서 디버깅 설정은 Run > Debug Configurations에서 할 수 있다. 좌측 리스트에서 C/C++ Application을 선택해 해당 exe를 선택한뒤 우측에서 Debugger 탭을 선택하면 Debugger를 선택할 수 있게 된다.

만약 gdb를 설치했음에도 불구하고 에러를 내면서 디버깅을 할 수 없는 경우 CMD창에서 다음과 같이 입력해보길 바란다.



만약 위처럼 메시지가 나오지 않고 libexpat-1.dll이 없다고 경고창이 나오면 현재 설치한 gdb버전이 libexpat-1.dll과 의존성이 있는 것이다. 이때는 libexpat-1.dll도 함께 다운로드 받아 MingGW/bin에 복사해줘야 한다. 

libexpat-1.dll은 아래 링크에서 다운로드 받는다.
http://downloads.sourceforge.net/project/mingw/MinGW%20expat/expat-2.0.1-1/libexpat-2.0.1-1-mingw32-dll-1.tar.gz

다음 글을 참고한다.
http://forums.codeblocks.org/index.php/topic,11301.msg77273.html

7. 정리하며 
프로젝트 중에 C와 MySQL을 연동하여 개발할 경우가 있어서 전체 환경설정을 정리한다는 마음으로 글을 적었다. 기존에 나와 있는 많은 글들이 너무 옛날 버전이라서 그런지 지금과 맞지 않는 부분도 있었다. 앞으로 MySQL과 연동하게 되면 관련 내용도 소개해 볼까 한다. 개발에 있어서 환경을 구축하고 적응하는게 반인 것 같다. ^^;


8. 참고글 

이클립스(Eclipse) CDT 설치
(Eclipse Galileo) C/C++ Developments User Guide
CDT를 이용한 Windows C/C++ 개발 환경 만들기 
Eclipse/CDT
Eclipse Project CDT (C/C++) Plugin Tutorial 1, 2By Brian Lee
이클립스(eclipse)를 이용해서 C/C++ 프로그래밍 환경설정
MinGW + Eclipse 를 이용한 Windows 개발 환경 구현 

글쓴이 : 지돌스타(http://blog.jidolstar.com/677)

googletest 환경 구축

 

 

안녕하세요. moltak입니다. 오늘은 TDD를 사용하기 위한 Google C++ Testing Frameworks를 설치해보고 예제를 돌려보겠습니다.

 

 

C++ Unit Test Framework는 굉장히 많습니다. JAVA는 JUnit과 Hamcrest라는 Framework 많이 사용하더군요. 하지만 C++은 언뜻 봐도 굉장히 많습니다. 저는 C++의 모든 Test Framework를 사용해본 것은 아닙니다. 그렇다고 Google Framework가 아주 좋다는 것도 아닙니다. 다만 사용하기 쉽고 굉장히 직관적이었습니다. (다른 Framework도 그런지는 모르겠네요. )

 

 

잔소리는 여기까지 하고 일단 사용해보도록 하겠습니다.

 

 

구글 Framework 또한 다른 라이브러리와 마찬가지로 아래 순서를 따르게 됩니다. 하나 하나 보도록 하죠.

1. Downloads

2. 설치

3. Visual Studio 설정

4. 사용하기

 

 

1. Downloads : : http://code.google.com/p/googletest/ 에 들어가서 상단에 Downloads 탭을 선택한 후 윈도우 버전 다운로드.

Figure 1 google test downloads

 

 

2. 설치 : 자신이 원하는 폴더에 압축해제. 그 후 gtest\msvc 폴더에 가서 gtest.sln 파일을 더블 클릭.

만약 버전이 안 맞아서 솔루션 파일을 변경해야 할 경우 .vcproj(프로젝트 파일)의 읽기 전용 속성을 해제하세요.

그 후 해당 솔루션을 컴파일 합니다.

 

 

3. VS 설정

VS2005~2008 : 도구->옵션->프로젝트 및 솔루션->VC++ 디렉터리

VS2010 : 프로젝트 옵션에서 설정해야 합니다.

포함 파일과 라이브러리 파일 경로 설정.

  • 포함파일에 \include 경로 설정
  • 라이브러리 파일에 \msvc\gtest\debug 경로 설정

Figure 2 Visual Studio Setting

 

 

위 그림처럼 하시면 됩니다.

 

Google Testing Framework는 런타임 라이브러리가 다중 스레드 디버그(/MTd) 이기 때문에 우리의 프로젝트 설정도 위 처럼 바꿔 줘야 합니다.

 

프로젝트 설정 -> 구성 속성 -> C++ -> 코드 생성 -> 런타임 라이브러리 -> 다중 스레드 디버그(/MTd)

Figure 3 런타임 라이브러리 변경

 

 

그 후 라이브러리 링크

 

이렇게 하시면 기본적인 설정 방법은 끝이 났습니다. 다른 라이브러리와 사용법이 같기 때문에 쉽게 하셨을 것 같네요.

 

 

4. 사용

이제 진짜로 사용해보도록 하죠.

 

문법은 위 그림과 같습니다. (http://soupim.tistory.com/48 참조)

사용 하실 때는 아래 소스처럼 하시면 쉽게 사용이 가능하십니다.

 

 

Figure 4 사용 예제 소스

 

 

저는 Test Fixtures를 사용해서 테스트를 수행하곤 하는데요. 이 방법이 Java나 다른 책에서 설명하는 TDD기법과 아주 유사합니다.

 

Figure 5 Test Fixtures 사용 예제

 

 

여러분들도 위 방법을 사용해서 테스트를 수행해보세요. 그리고 테스트 이름은 한글로 하는 것이 좋다고 하더라고요. (채수원 : 고품질 쾌속개발을 위한 TDD 실천법과 도구(한빛미디어))

위 책을 보고 있는데요. 상당히 좋습니다.

 

Figure 6 실행 화면

 

 

5. 정리

이렇게 해서 Google Testing Framework 설치와 사용법이 설명이 끝났습니다. 많이 사용해 보시고 저한테도 알려주셨으면 감사하겠습니다. ^^

그리고 Google Test UI도 있는데요. 아래 경로로 찾아 들어가시면 됩니다.

Figure 7 Google Test UI

 

 

위 손가락 위치에 가시면 다운 받으실 수 있습니다. 상당히 보기 편하더라고요. 다른 Unit Test 툴처럼. 하지만 저만 그런지는 모르겠으나. 굉장히 느립니다. 5초 이상 걸리는 것 같습니다. 다른 분들도 한번씩 사용해 보세요. 더 보기 좋답니다. ^^

 

 

이만 마치도록 하겠습니다.

 

Bloger : moltak.net

디모그 모드에서 프로그램을 종료하면 메모리 릭이 발생하는 경우가 있다.
그때 vs의 output 창에 아래와 같은 메시지가 나온다.


Detected memory leaks!
Dumping objects ->
{130} normal block at 0x004866F0, 712 bytes long.
 Data: <xA  8bH       ' > 78 41 03 10 38 62 48 00 01 CD CD CD 02 00 27 11 


이 메모리 릭을 어떻게 찾아야 하나 막막했다.
그런데 CRT에는 릭을 감지하는 debug function들이 있다. 이 함수들을 사용하면 메모리 릭이 있는 위치를 찾을 수 있다.

한가지 덧 붙이자면 릭 메시지 안의 {130} 의 의미는 프로그램에서 몇번째로 할당 받은 영역이라는 것이다. 위 메시지는 130번째로 할당받았다는 의미다.

메모리 릭을 추적하기 위해 Crt 함수를 사용하면 된다. Crt 함수를 사용하기 위해서는 다음 순서를 반드시 따라야 한다.

#include <stdlib.h>
#include <crtdbg.h>

_CrtDumpMemoryLeaks(); // 이 함수는 output 창에 메모리 릭 정보를 출력시킨다.
_CrtSetBreakAlloc( 130 ); // 이 함수는 130번째 메모리를 할당하려고 할 때 프로그램을 break 시켜준다.
_crtBreakAlloc = 130; // 이렇게 사용할 수 도 있다.

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
이 문은 프로그램이 종료될 때 자동으로 _CrtDumpMemoryLeaks를 호출한다.


_CrtSetDbgFlag 함수는 다섯개의 Flag 가 있다.
_CRTDBG_ALLOC_MEM_DF : 디폴트로 켜져 있으며, 디버그 버전에서 모든 메모리 할당이 일어날 때마다 추적 가능하도록 특별한 기능을 추가해 준다. 이 플래그가 켜져 있어야 메모리 누수를 안전하게 검사할 수 있다.

_CRTDBG_DELAY_FREE_MEM_DF : delete, free 등으로 삭제되어도 바로 삭제되지 않고, CRT의 메모리 관리소에 남아 있다가 프로그램 종료시에 완전히 삭제된다.

_CRTDBG_CHECK_ALWAYS_DF : 모든 메모리관련 연산에서 _CrtCheckMemory를 호출한다.

_CRTDBG_CHECK_CRT_DF : CRT가 내부적으로 할당한 블록도 메모리를 체크할 때 포함한다. 일반적으로는 CRT가 할당한 블록은 메모리 체크에서 제외된다. 일반적으로 사용하지 않는다.

_CRTDBG_LEAK_CHECK_DF : 프로그램이 완전히 종료되기 직전에 아직 해체되지 않는 메모리가 있는지 검사한다. 프로그램의 종료 포인트가 여러운데 있는 경우에 사용하면 일일이 _CrtDumpMemoryLeaks 메소드를 호출하지 않아도 자동적으로 메모리 누수를 검사할 수 있게 된다.

이중 _CRTDBG_ALLOC_MEM_DF를 제외하고는 모두 디폴트로 꺼져 있다. 그러므로 다음과 같이 메모리 검사 기능을 켜도록 해야한다. 
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
// MFC의 경우는 위의 옵션이 활성화 되어 있다.


Bloger : moltak.net

'Programming > 이것저것' 카테고리의 다른 글

[펌] valgrind 를 이용한 메모리 관리  (0) 2011.03.15
Doxygen - 작성중  (0) 2011.03.08
typeid 2  (1) 2010.05.25
세그먼트 레지스터  (0) 2010.05.01
x86 Register  (0) 2010.04.30
예전에 typeid 포스팅을 한 적이 있습니다. (http://moltak.net/search/typeid) 참조
열심히 플젝을 하던 중 원하는 결과값이 안나와서 왜 그런가 하고 한시간 가량 삽질 끝에 알아 냈네요.;;

위 포스팅을 보시면 typeid( type ).name()을 통해서 type의 이름을 얻어 오는 것이 있습니다.
.name() 함수가 현재 타입을 알려주는 역할을 하죠.
저는 아래와 같이 사용하고 있었습니다.


다들 아시겠지만 우리가 원하는 결과는?? 젤 아래 결과가 당연히 Sub가 나와야 맞습니다.
하지만 그렇지 않더군요. 결과를 먼저 볼까요?

위와 같이 전부 Super 클래스가 나왔네요?? 왜 그런걸까요? 제가 잘 못했겠죠?? 아직 확실한 이유는 모르지만 결과를 올바르게 바꾸는 방법은 알아 냈습니다.





바로 위 소스와 같이 사용하지 않는 하나의 함수를 집어 넣는 것입니다. C++은 상속을 받았을 때, 가상함수 테이블이 생기게 됩니다. typeid는 클래스의 경우 가상함수 테이블을 보고 type을 결정짓지 않나 생각이 드네요.
정확히 아시는 분은 알려주세요. ㅠㅠ 기다리겠습니다. ㅋㅋ


Bloger: moltak.net


'Programming > 이것저것' 카테고리의 다른 글

Doxygen - 작성중  (0) 2011.03.08
_Crt Debug Functions  (0) 2010.07.23
세그먼트 레지스터  (0) 2010.05.01
x86 Register  (0) 2010.04.30
어셈블리어 점프 명령어  (0) 2010.04.29

NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

드라이버를 공부하시려면 꼭 기억해야 될 내용이 있습니다. 일반적인 드라이버를 짤 때 우리는 아래 그림과 같은 문장을 사용합니다.

이 그림이 뭘 의미 하는 걸까요? 바로 콜백함수의 등록입니다. NDIS 드라이버도 마찬가지지만 콜백을 잘 끼워 맞추기만 하면 됩니다.

콜백의 기능, 전체적인 콜백 호출 흐름, 각 콜백 안에서 호출해야 할 API들을 파악했다면 NDIS의 절반 이상을 이해한 것이라고 합니다. (참조: http://xeraph.com/4787739)

 

 

IntermediateDriver의 초기화는 처음 공부하는 저에게는 상당히 어렵더군요. (사실 아직도 이해하는 중입니다.)

이 글에서는 일반적인 드라이버의 DriverEntry와 Intermediate 드라이버의 DriverEntry를 비교하겠습니다. 그래서 어떻게 다른지 개략적으로 설명하고 다음 글에서부터 본격적으로 분석을 해보도록 하겠습니다.

Intermediate 드라이버의 예제는 DDK 폴더 안의 passthru라는 예제가 있습니다. 그 예제를 기반으로 설명하겠습니다.

 

일반적인 드라이버의 경우 IoCreateDevice를 호출해서 드라이버를 생성하게 됩니다. 그 후 심볼릭(Symbolic) 링크를 만들고 MajorFunction(DDK WDM 문서 참조)의 콜백함수를 지정하는 것으로 넘어가게 됩니다.

 

 

하지만 NDIS 드라이버의 경우 많이 다릅니다. 우리가 작성하려고 하는 NDIS Intermediate Driver의 예를 들자면 여러 초기화 과정이 필요하게 됩니다.

passthru의 DriverEntry 함수를 보시면 크게 네 개의 초기화 단계(아래 그림 참조)로 나눌 수 있습니다.

또한, DDK 문서(참고: moltak.net: NDIS Driver 02) Intermediate Driver)에 MiniportXxx, ProtocolXxx함수를 노출시켜야 한다고 설명하고 있습니다.

그래서 NDIS의 초기화 단계는 Miniport, Protocol Driver의 콜백함수를 설정해야 합니다.

 

 

 

1. NdisMInitializeWrapper을 호출하고 NdisWapperHandle에서 리턴된 핸들을 지정한다.

2. 드라이버의 MiniportXxx 함수들을 등록하기 위해서 NdisIMRegisterLayeredMiniport를 호출하고 스텝 1에서 얻어진 핸들을 인자로 보낸다.

NdisMinitializeWrapper 함수를 호출해서 NDIS_HANDLE을 얻어 올 수 있습니다.(NdisWrapperHandle 변수)

그리고 이 변수를 이용해서 우리는 MiniportXxx와 ProtocolXxx를 노출 시켜줄 수 있습니다.

위 소스에서 MChars라는 변수에 여러 가지 콜백함수를 설정하고 있는 것을 볼 수 있습니다.

현재는 이것을 통해서 콜백을 등록하고 가장 아래 있는 NdisIMRegisterLayeredMiniport를 이용 MiniportXxx를 등록한다고만 아시면 됩니다. (자세한 설명은 다음 블로깅을 통해 하도록 하겠습니다.)

 

 

3. 만약 드라이버가 그 자신을 밑의 NDIS 드라이버에게 다음에 바인드 한다면 드라이버의 ProtocolXxx 함수들을 등록하기 위해서 NdisRegisterProtocol을 호출한다.

위 소스도 ProtocolXxx함수를 노출시키기 위해서 하는 것입니다. 각종 콜백함수를 등록하고 아래에 있는 NdisRegisterProtocol을 통해 인터미디엇 드라이버의 ProtocolXxx함수들을 노출시킵니다. 각 콜백함수의 내용은 복잡하고 역할은 아직 잘 모릅니다. (알아야 할게 너무 많네요ㅠㅠ)

 

 

4. 만약 드라이버가 MiniportXxx와 ProtocolXxx함수들 둘 다를 드러낸다면, 드라이버의 미니포트 하위경계와 프로토콜 상위경계에 대해서 NDIS 라이브러리를 형성하기 위해서 NdisIMAssociateMiniport를 호출한다.

우리는 MiniportXxx와 ProtocolXxx함수를 노출하길 원합니다. (노출하기 원하지 않다면 한 개의 핸들만 넣어도 되는 건지는 확실하지 않네요. ㅠㅠ)

NdisIMAssociateMiniport 함수는 NDIS에게 미니포트와 프로토콜을 위한 특정 lower와 upper 인터페이스들이 각각 같은 인터미디엇 드라이버에 속한다는 것을 알립니다.

 

 

여기까지 해서 DriverEntry에 대한 개략적인 설명이 끝났습니다. 원본 소스파일은 ddk\src\network\ndis\passthru\driver\passthru.c 파일을 참조하시기 바랍니다.

다음은 인터미디엇 드라이버의 DriverEntry에서 Miniport를 등록하는 부분을 더욱 세세하게 설명을 하도록 하겠습니다. 내용이 많아서 몇 챕터로 쪼개서 해야겠네요. 아무튼 모두들 즐공! 즐프! 하세요.

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18

NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

NDIS 드라이버는 Miniport, Intermediate, Protocol 타입의 네트워크 드라이버들을 제공합니다.

3타입의 네트워크 드라이버들이 어떤 역할을 하는지 차근차근 알아보도록 하겠습니다.

 

 

1. Miniport Driver

Miniport Driver(이하 미니포트 드라이버)는 두 가지 역할을 수행합니다.

그림에서 보시는 바와 같이 NIC(Network Interface Card)바로 위에 위치해 있습니다. 미니포트 드라이버는 NIC을 통해 데이터를 보내고 받는 것을 포함해서, NIC을 관리합니다. 또, Intermediate Driver(이하 인터미디엇 드라이버)와 같은 상위 레벨 드라이버들과 통신합니다.

 

미니포트 드라이버는 NDIS 라이브러리를 통해 NIC과 그리고 상위 레벨 드라이버들과 통신합니다. NDIS 라이브러리는 미니포트가 호출하는데 필요한 운영체제의 모든 시스템 함수들을 캡슐화하는 NdisXxx함수들을 익스포트 합니다. 미니포트 드라이버는 상위 레벨 드라이버들이 미니포트 드라이버에 접근하기 위해서 또는, 자기 자신을 위해서 NDIS가 호출하는 엔트리 포인트들(MiniportXxx 함수들)을 익스포트 해야 합니다. 송/수신 연산들(패킷을 보내고 받고 하는 것을 말하는 듯)은 미니포트 드라이버들과 NDIS 상위 레벨 드라이버들간에 상호 작용입니다.

 

- 전송 계층 드라이버가 전송하고자 하는 패킷들을 가지고 있을 때, 전송 계층 드라이버는 NDIS라이브러리에 의해 익스포트 되어지는 NdisXxx 함수를 호출합니다. NDIS는 그러고 나서 미니포트에 의해 익스포트된 적당한 MiniportXxx함수를 호출함으로써 미니포트에게 패킷을 전달합니다. 패킷을 받은 미니포트 드라이버는 적당한 NdisXxx함수들을 호출함으로써 전송을 위해 NIC에게 패킷을 포워드 합니다.

 

- NIC이 패킷을 수신할 때, NDIS 혹은 NIC의 미니포트에 의해 처리될 수 있는 하드웨어 인터럽트를 포스트 할 수 있습니다. NDIS는 적당한 MiniportXxx함수를 호출함으로써 NIC의 미니포트 드라이버에게 알립니다. 미니포트 드라이버는 NIC으로부터 데이터 전송을 설정하고 그리고나서 적당한 NdisXxx 함수를 호출함으로써 바인드된 상위레벨 드라이버들에게 수신된 패킷의 존재를 (Indicate)알립니다.

 

 

2. Intermediate Driver

 

드라이버 계층도에서 보면 인터미디엇 드라이버는 Protocol Driver(이하 프로토콜 드라이버)와 미니포트 드라이버들 사이에 위치합니다. 그래서 "위"의 프로토콜 드라이버와 "아래"의 미니포트 드라이버들과 통신을 수행해야 합니다.

 

- Lower Edge에서 인터미디엇 드라이버는 NDIS가 미니포트 드라이버와 통신하기 위해 호출하는 프로토콜 엔트리 포인트들(ProtocolXxx 함수들)을 노출합니다. 미니포트 드라이버가 인터미디엇 드라이버를 볼 때 인터미디엇 드라이버는 프로토콜 드라이버가 되는 것으로 나타납니다.

 

- Upper Edge에서 인터미디엇 드라이버는 NDIS가 프로토콜 드라이버와 통신하기 위해 호출하는 미니포트 엔트리 포인트들(MiniportXxx 함수들)을 노출합니다. 프로토콜드라이버가 인터미디엇 드라이버를 볼 때 인터미디엇 드라이버는 미니포트 드라이버가 되는 것으로 나타닙니다.

 

- 인터미디엇 드라이버 요약 정리: 인터미디엇 드라이버는 upper edge에서 MiniportXxx 함수들의 subset을 익스포트 합니다. 하지만 실제로 물리 NIC을 관리하지는 않습니다. (NIC의 관리는 Miniport Driver가 합니다.) 그 대신에, 인터미디엇 드라이버 위의 프로토콜들이 바인드 할 수 있는 하나, 혹은 그 이상의 가상 어댑터들을 익스포트 합니다. 그리고 프로토콜 드라이버들은 인터미디엇 드라이버에 의해 익스포트되어지는 가상 어댑터들이 물리 NIC이 되는 것으로 보이게 됩니다.

프로토콜 드라이버가 가상 어댑터(인터미디엇 드라이버가 익스포트 한)에 요구 혹은 패킷들을 보낼 때, 인터미디엇 드라이버는 이런 요청과 패킷을 아래 미니포트 드라이버에 전달하게 됩니다.

 

- 인터미디엇 드라이버는 일반적으로 다음과 같이 사용됩니다.

다른 네트워크의 사이를 변환하기 위해: 예를 들어, Ethernet과 Token Ring 전송 계층들과 ATM 미니포트 사이에 인터미디엇 드라비어의 함수는 Ehternet과 Token Ring 패킷들을 ATM패킷들로 맵하거나 그 반대로 맵합니다.

패킷들을 필터하기: 방화벽 같은 것을 만들 때 사용합니다.

하나 이상의 NIC과 관련해서 패킷 전송의 균형을 맞춘다: 패킷을 분산합니다.(??)

 

 

3. Protocol Driver

드라이버들의 NDIS 계층도에서 가장 위에 있는 프로토콜 드라이버는 TCP/IP혹은 IPX/SPX 스택과 같은 전송 프로토콜 스택을 실행하는 전송 계층 드라이버내에서 가장 낮은 레벨 드라이버로서 사용됩니다. 전송 계층 드라이버는 패킷들을 할당하며 어플리케이션이 보내는 데이터를 패킷에 복사하며, 또 이러한 패킷들을 NDIS 함수들을 호출함으로써 낮은 레벨 드라이버에게 보냅니다. 프로토콜 드라이버는 낮은 레벨 드라이버로부터 들어오는 패킷들을 수신하기 위해 프로토콜 인터페이스를 제공합니다. 전송 계층 드라이버는 수신된 데이터를 요청된 클라이언트 어플리케이션에 전송합니다.

 

Lower Edge에서 프로토콜 드라이버는 인터미디엇 드라이버들과 미니포트 NIC드라이버들에 인터페이스 합니다. 프로토콜 드라이버는 패킷들을 보내기 위해서 NdisXxx함수들을 호출하고, Lower 레벨 드라이버들에 의해 유지된 정보를 읽고 설정하고 운영체제 서비스들을 사용합니다. 프로토콜 드라이버는 NDIS가 수신한 패킷들을 위로 전송하기 위해서 그리고 Lower 드라이버들의 상태를 알기 위해, 혹은 자신의 목적을 위해 호출하는 엔트리 포인트들(ProtocolXxx 함수들)의 집합을 익스포트 합니다.

 

Upper Edge에서 전송 계층 프로토콜 드라이버는 프로토콜 스택에서 상위 레벨 드라이버에 대한 private 인터페이스를 갖게 됩니다.

 

 

4. 정리

위 그림은 이제까지 설명해왔던 내용을 알기 쉽게 나타내 주는 그림입니다. (제 개인적인 생각)

위 그림에서는 Intermediate Driver가 빠져 있습니다. 대신 Wrapper가 포함되어 있죠. 이 것을 보고 여러가지로 생각 할 수 있겠지만 오늘 공부한 내용을 토대로 생각해 본다면 Intermediate Driver는 단순히 Miniport Driver의 Wrapper로 생각할 수 있다는 것입니다. (Miniport <-> Intermediate <-> Protocol 의 관계를 생각해 보세요) Intermediate Driver를 Miniport에 대한 Wrapper로 생각한다면 이해하기가 더 쉽습니다. 어떤 요청이던지 저 방어망을 치고 있는 Wrapper를 뚫지 않고서는 Miniport에게 갈 수가 없습니다. 그리고 Wrapper는 Upper Edge에 대해서는 자신이 Miniport인 것처럼 행세 할 것이며 Lower Edge에 대해서는 Protocol인양 행세 할 것입니다.

다만 NIC과 Miniport Driver와의 관계는 좀 이상하긴 하지만 그거 빼고는 맞는 것 같습니다. (아하하하하하;;)

이 글에서 가장 중요한 것은… 바로 제 프로젝트를 완수 하려면 어떤 드라이버에서 해도 상관 없지만 보통 Intermediate Driver에서 수행한다는 것입니다. (사실 Miniport에서도 할 수 있고 Hook Driver를 만들어서도 할 수 있습니다.)

 

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 03) Intermediate Driver 초기화  (0) 2010.05.09
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
이 자료는 정말 마음에 드네요. (아직 다 보지는 못했지만)


Thomas F. Divine님과 James Antognini님이 작성한 문서입니다.
DDK를 깔면 예제로 깔리는 PassThru를 확장해서 설명해 놓으셨습니다.
처음 Intermediate(IM) Driver를 공부하려고 하면 정말... 어떻게 해야 할지 막막했습니다.
DDK 문서와 이 문서를 갖고 계속 공부를 해 나가야겠습니다.
그럼 모두 즐프하세요.


Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 03) Intermediate Driver 초기화  (0) 2010.05.09
NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18

NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

Chapter1 네트워크 드라이버 디자인 가이드에 대한 로드맵

Windows2000(XP, 2003 포함)은 세가지 기본 타입의 커널 모드 네트워크 드라이버들을 제공합니다. 이 세가지 타입에 대해서 정확히는 아니더라도 대략적으로 알고 있어야 차후 드라이버를 작성할 때 선택해서 할 수 있을 것입니다. 그러니 세 개다 살펴 보도록 하겠습니다. 그 전에 먼저 Windows의 Network Layer 부 터 알아보도록 하겠습니다.

 

 

위에 보시는 것이 Windows의 Network Layer입니다.

[참조: http://subsub.windowstest.net/bbs/view.asp?tb=ndis&no=221 ]

 

보통 Network 드라이버를 짤 때 NDIS와 TDI를 사용하게 됩니다. 만약 TDI Filter를 개발한다면 얻을 수 있는 것은 IP, Port, Application Protocol(TCP 이후의 데이터)를 얻을 수 있으며 모니터링, 변조, 차단등을 할 수 있다고 합니다. NDIS Protocol Driver를 개발한다면 Ethernet Header, IP Header, TCP Header, App Protocol까지 모든 Raw Packet의 정보를 얻을 수 있다고 하네요. 하지만 직접적인 변조, 차단을 할 수 없다고 합니다. 그것을 하기 위해서는 NDIS Intermediate 드라이버나 NDIS Hook Driver 혹은 WFP(Windows Filtering Platform) 드라이버를 작성해야 한다고 합니다.

 

 

 

1. Miniport NIC Drivers

미니포트 드라이버는 직접 NIC을 관리하고 상위 레벨 드라이버들에 대한 인터페이스를 제공한다. (NDIS DDK 문서)

 

 

2. Intermediate Drivers

인터미디엇 프로토콜 드라이버는 legacy 전송 드라이버와 같은 상위 레벨 프로토콜 드라이버들과 미니포트 사이에 인터페이스이다. 일반적인 인터미디엇 프로토콜 드라이버를 개발하는 일반적인 이유는 존재하는 legacy 드라이버와 전송 드라이버에 알려지지 않은 새로운 미디어 타입을 위한 NIC을 관리하는 미디포트 사이에 미디어 전환을 행하는 거다.

 

 

3. Protocol Drivers

상위 레벨 프로토콜 드라이버는 TDI 인터페이스를 실행하거나 네트워크 사용자들에 대한 서비스들을 제공하기 위해 상위 edge에 또 하나의 어플리케이션 특정 인터페이스를 행한다. lower edge에 이러한 타입의 드라이버는 다음 lower 드라이버로부터 들어오는 패킷들을 수신하고 패킷들을 프로토콜 인터페이스에 제공한다. 또 하나의 타입의 프로토콜 드라이버는 연결 지향 콜 매니저이다. 콜 매니저는 프로토콜 드라이버인 연결 지향 클라이언트들을 위해 서비스들을 콜 설정하고 tear-down 을 제공한다.

 

 

Windows2000에 의해 제공되는 또 하나 타입의 커널 모드 드라이버는 필터 hook 드라이버이다. 필터 패킷들에 사용되는 필터-hook 드라이버는 운영체제에 의해 제공되는 IP 필터 드라이버의 기능을 확장한다.

작성하려고하는 드라이버 타입의 상관없이 Part 1, Network Drivers Design Guide 의 Chapter 2-3을 읽어야 한다. 이러한 장들은 Windows2000네트워크 아키텍처와 프로그래밍 고려 사항들을 토론한다. 또한 Part5, Chapter 1을 읽어야 한다. 이 장은 네트워크 요소들을 인스톨하기 위해 사용된 네트워크 INF 파일들을 토론한다. 만약 네트워크 드라이버가 예를 들어 바인딩을 제어하기 위해 notify 객체를 요구한다면은, Part 5, Chapter 2를 읽어라.

읽어야 할 추가적인 chapters들을 알기 위해, 다음 그림에서 적당한 드라이버 타입을 클릭하라. 이것은 드라이버 타입의 선택을 재 정의하도록 하고 그 섹션으로 점프할 것이다.

Miniport Drivers

작성할 다음과 같은 타입을 선택한다.

Connectionless Miniport

만약 Ethernet, FDDI, 혹은 Token Ring과 같은 비연결 지향 네트워크 미디어을 위해 NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chaters 1-7, 9을 읽어라.

WAN Miniport

만약 WAN NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chapters 1-9를 읽어라.

Connection-Oriented Miniport

만약 ATM 혹은 ISDN과 같은 연결 지향 네트워크 미디어을 위한 NIC을 제어하는 미니포트를 쓴다면은,

Part 2, Chapters 1-7, 9
Part 4, Chapter 1을 읽어라.

Integrated Miniport Call Manager(MCM)

만약 콜 매니저 서비스들을 제공하는 연결 지향 NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chapters 1-7, 9
Part 3, Chapter 2
Part 4, Chapter 1 를 읽어라.

 

 

Intermediate Drivers

작성할 인터미디엇 타입을 선택한다.

With a Connectionless Lower Edge

만약 lower edge가 비연결지향 미니포트들에 대한 인터페이스를 제공하는 인터미디엇 드라이버를 작성한다면은

Part 3, Chapter 1을 읽어라.

With a Connection-Oriented Lower Edge

만약 lower edge가 연결 지향 미니포트들에 대한 인터페이스를 제공하는 인터미디엇 드라이버를 제공한다면은,

Part 3, Chapter 1
Part 4, Chapter 4를 읽어라.

 

 

Protocol Drivers

작성할 프로토콜 드라이버의 타입을 선택한다.

With a Connectionless Lower Edge

만약 lower edge가 비연결지향에 대한 인터페이스를 제공하는 프로토콜 드라이버를 작성한다면은,

Part 3, Chapters, 2를 읽어라.

With TDI upper edge

TDI upper edge를 가지는 프로토콜를 작성한다면은

Part 3, Chapters, 2, 3, 4, 5를 봐라.

With Winsock support

만약 Winsock 지원을 제공하는 프로토콜을 작성한다면은,

Part 3, Chapters, 2, 3, 4, 5, 6을 봐라.

Connection-Oriented Client or Call Manager

만약 연결 지향 미니포트들에 대한 인터페이스를 제공하는 연결 지향 클라이언트를 작성하거나, 연결 지향 콜 매니저를 작성한다면은

Part 3, Chapter 2
Part 4, Chapter 1을 봐라.

 

 

Filter-hook Drivers

Part 6, Chapter 1을 봐라.

 

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18

오늘은 메모리 구조에서 가장 복잡하다고 느끼는 세그먼테이션에 대해서 정리하겠습니다.

x86에서는 segmentation과 paging 기법을 이용하여 [가상 메모리] 를 만들고 프로그램들을 실행시키게 됩니다.

그림 1 Physical Address 변환 과정

 

가상 메모리는 세그먼테이션 과정을 거치고 페이징 과정을 거쳐서 실제 메모리가 나오게됩니다.

이때 세그먼테이션에는 Selector와 Offset이 들어가게 되는데 Selector는 이 챕터의 제목인 세그먼트 레지스터를 말합니다. Offset은 가상주소를 말합니다.

 

그냥 말로 서술하면 보기 힘드니 숫자를 붙여서 설명을 해 드리겠습니다.

 

세그먼테이션 과정

  1. 가상주소를 물리 주소로 바꾸려면 Selector(세그먼트 레지스터)와 Offset(가상주소)이 필요합니다.
  2. Selector는 16bit 이며 Descriptor Table의 Index를 가리킵니다. (그림 참조)
  3. Selector(세그먼트 레지스터)는 Descriptor table의 Segment Descriptor(그림 참조)를 가리킵니다.
  4. Segment Descriptor의 Base 주소와 가상주소를 합쳐서 선형 주소를 만들어 냅니다.

 

세그먼트 디스크립터 안의 내용은 굳이 설명하지 않아도 될 것 같네요. 다만 Base Address 0-15만 알면 될 것 같습니다. Base Address 필드는 실제 세그먼트를 통해 메모리에 접근할 때 더하는 값입니다. 아까 세그먼트 디스크립터의 Base주소와 가상주소를 더해서 32bit 선형 주소를 만든다고 했었죠? 그때 사용 되는 것입니다.

 

이제까지 저는 세그먼트 레지스터가 16bit라고 설명을 했지만 사실 80bit 입니다. 나머지 64bit은 왜 설명 안 했냐? 하신다면 했습니다. 위에서 말한 세그먼트 디스크립터가 바로 세그먼트 레지스터의 안 보이는 나머지 64bit입니다. 왜 80bit으로 만들었는지 잘 모르겠지만 많이 추측 하는 것은 세그먼트 레지스터는 자주 사용하고 자주 사용한다면 속도가 빠른 레지스터에 올리는 것이 더 낫다고 생각됩니다.

 

이젠 세그먼트 레지스터를 직접 보도록 하겠습니다. Ollydbg와 Windbg를 사용하겠습니다.

Ollydbg에서 열면 6개의 세그먼트 레지스터를 볼 수 있습니다. x86은 6개의 세그먼트 레지스터가 있습니다. 그 중 노란색으로 표시된 FS 레지스터를 보겠습니다.

FS는 Selector로 동작되며 INDEX, TI, RPL(그림 참조)필드로 이루어져 있는 것을 알 수 있습니다.

그래서 이진수로 표현하면 0000 0000 00111 0 11 가 나옵니다. 앞에 13비트는 테이블에서의 세그먼트 디스크립터 위치고 그 다음 1 비트는 GDT인지 LDT인지(인터넷 참고)를 나타내며 다음 2비트는 권한(인터넷 참고)을 나타냅니다. 중요한 것은 7번째를 가리키고 있다는 것입니다.

 

위 그림을 보시면 선택되어 있는 부분이 FS레지스터가 가리키는 세그먼트 디스크립터입니다. Ollydbg에 나온 값이랑 똑같네요.

 

 

여기까지 해서 세그먼트 레지스터와 선형 주소를 만드는 것을 보았는데요. 생각보다 어렵다고 느끼실 수도 있습니다. 하지만 조금만 공부하시고 더 자료를 찾아 보시면 정리를 완벽히 하실 수 있을 겁니다.

그럼 모두 즐공 하세요.

 

 

Bloger: moltak.net

'Programming > 이것저것' 카테고리의 다른 글

_Crt Debug Functions  (0) 2010.07.23
typeid 2  (1) 2010.05.25
x86 Register  (0) 2010.04.30
어셈블리어 점프 명령어  (0) 2010.04.29
Symbol  (0) 2010.04.24

IA 32(x86) CPU는 크게 5종류의 레지스터가 있습니다.

범용 레지스터, 인덱스 레지스터, 포인터 레지스터, 부동 소수점 레지스터, 플래그 레지스터가 그것이며 각각 사용용도가 모두 다릅니다.

레지스터들 앞에 붙어있는 E는 Extended의 약자로서 현재 사용되는 x86 architecture는 80386에서 점차 발전해 나갔습니다.

그래서 현재 많이 사용되는 Pentium 이나 Core 2DUO 같은 프로세서들도 80386과 거의 비슷합니다. 물론 엄~~청 나게 발전 되었지만요. 

종류

이름

설명

범용

EAX

곱셈과 나눗셈 명령에서 자동으로 사용되고 함수의 리턴값이 저장되는 용도로 사용된다.

EBX

ESI EDI 결합하여 인덱스에 사용된다.

ECX

반복 명령어 사용시 카운터로 사용된다. ECX 레지스터에 반복할 횟수를 지정해 놓고 반복 작업을 수행한다.

EDX

EAX 같이 쓰이며 부호 확장 명령 등에 쓰인다.

인덱스

ESI

데이터 복사나 조작시 Source Data 주소가 저장된다. ESI 레지스터가 가리키는 주소의 데이터를 EDI 레지스터가 가리키는 주소로 복사하는 용도로 많이 사용된다.

EDI

복사 작업시 Destination 주소가 저장된다. 주로 ESI 레지스터가 가리키는 주소의 데이터가 복사된다.

포인터

EIP

다음에 실행해야 명령어가 존재하는 메모리 주소가 저장된다. 현재 명령어를 실행 완료한 후에 EIP 레지스터에 저장되어 있는 주소에 위치한 명령어를 실행하게 된다. 실행 EIP 레지스터는 다음 실행해야 명령어가 존재하는 주소의 값이 저장된다.

EBP

하나의 스택 프레임의 시작 지점 주소가 저장된다. 현재 사용되는 스택 프레임이 소멸되지 않는 동안 EBP 값은 변하지 않는다. 현재의 스택 프레임이 소멸되면 이전에 사용되던 스택

프레임을 가리키게 된다.

ESP

하나의 스택 프레임의 지점 주소가 저장된다. PUSH, POP 명령어에 따라서 ESP 값이 4byte 변한다.

부동

소수점

ST(0)

부동 소수 연산에 사용되는 레지스터

ST(1)

ST(2)

ST(3)

ST(4)

ST(5)

ST(6)

ST(7)

플래그

Eflag

OF

Overflow: 산술 연산 상위(가장 왼쪽) 비트의 overflow 나타냄

DF

Direction: 스트링(문자) 데이터를 이동시키거나 비교할 왼쪽 또는 오른쪽의 방향 결정

IF

Interrupt: 키보드 입력과 같은 외부 인터럽트가 처리되어야 하는지 또는 무시되어야 하는지를 나타낸다.

TF

Trap: 단일 단계 모드(single-step mode) 프로세서 연산을 허용한다. 디버거 프로그램은 TF 플래그를 설정해서, 사용자가 번에 하나씩 명령어를 실행시키고, 레지스터와 메모리 상에서 영향을 조사할 있게 한다.

SF

Sign: 산술 연산의 결과 값에 대한 부호를 나타낸다. (0=양수, 1=음수)

ZF

Zero: 산술이나 비교 연산의 결과를 나타낸다. (0= 결과 값이 0 아님, 1= 결과 값이 0)

AF

Auxiliary carry: 특수화된 산술에서 사용되며, 산술 연산에서 비트 3에서 비트 4로의 캐리를 포함한다.

PF

Parity: 연산 겨로가 1비트들의 개수를 나타낸다. 개수가 짝수인 경우 짝수 패리티(even parity) 부르며, 홀수인 경우 홀수 패리티(odd parity) 한다.

CF

Carry: 산술 연산 상위 비트의 캐리를 포함한다. 또한 비트 자리이동(shift) 또는 비트 회전(rotate) 연산 가장 마지막의 비트 내용을 포함한다.

  

'Programming > 이것저것' 카테고리의 다른 글

typeid 2  (1) 2010.05.25
세그먼트 레지스터  (0) 2010.05.01
어셈블리어 점프 명령어  (0) 2010.04.29
Symbol  (0) 2010.04.24
IL Code에 심볼 정보가 포함되는 이유  (0) 2010.04.24

참고 : http://blog.naver.com/saint_05

리버싱을 하다보면 조건 점프 명령이 많이 나와서 한번 올려봅니다.

외울 필요는 없구요 그냥 필요할 때 보는 정도로 사용하시면 될 것 같습니다.

어셈명령어

의미

점프 조건

(레지스터상태)

JA

결과가 1보다 클 경우 점프

CF=0 and ZF=0

JAE

결과가 1보다 크거나 같을 경우 점프

CF=0

JB

결과가 1보다 작을 경우 점프

CF=1

JBE

결과가 1보다 작거나 같을 경우 점프

CF=1 or ZF=1

JC

캐리 플래그가 1일 경우 점프

CF=1

JCXZ

CX가 0일 경우 점프

CX=0

JE

결과가 같을 경우 점프

ZF=1

JECXZ

ECX가 0일 경우 점프

ECX=0

JG

결과가 클 경우 점프(signed)

ZF=0 and SF=OF

JGE

결과가 크거나 같을 경우 점프 (signed)

SF=OF

JL

결과가 작을 경우 점프(signed)

SF != OF

JLE

결과가 작거나 같을 경우 점프 (signed)

ZF=1 or SF != OF

JMP

점프

없음

JNA

결과가 작을 경우 점프

CF=1 or ZF=1

JNAE

결과가 작거나 같을 경우 점프

CF=1

JNB

결과가 클 경우 점프

CF=0

JNBE

결과가 크거나 같을 경우 점프

CF=0 and ZF=0

JNC

캐리 플래그가 0일 경우 점프

CF=0

JNE

결과가 클 경우 점프

ZF=0

JNG

결과가 작을 경우 점프(signed)

ZF=1 or SF != OF

JNGE

결과가 작거나 같을 경우 점프(signed)

SF != OF

JNL

결과가 클 경우 점프(signed)

SF=OF

JNLE

결과가 크거나 같을 경우 점프(signed)

ZF=0 and SF=OF

JNO

오버 플로우 하지 않으면 점프(signed)

OF=0

JNP

패리티 플래그가 0일 때 점프

 

PF=0

JNS

결과가 Signed 가 아닐 때 점프(signed)

SF=0

JNZ

결과가 0 이 아닐 때 점프

ZF=0

JO

오버 플로우 일 경우 점프(signed)

OF=1

JP

패리티 플래그가 1일 때 점프

PF=1

JPE

패리티가 같을 때 점프

PF=1

JPO

패리티가 홀수 이면 점프

PF=0

JS

Sign플래그가 1일 때 점프

SF=1

JZ

0이면 점프

ZF=1

좀 더 자세히 알고 싶으시면 http://asmlove.co.kr 에서 확인 해 보시길 바랍니다.

'Programming > 이것저것' 카테고리의 다른 글

세그먼트 레지스터  (0) 2010.05.01
x86 Register  (0) 2010.04.30
Symbol  (0) 2010.04.24
IL Code에 심볼 정보가 포함되는 이유  (0) 2010.04.24
초기화 하지 않은 메모리  (0) 2010.04.16

사실 저도 심볼 심볼만 하고 있었지 이 녀석이 무엇인지 어떤 역할을 하는지 잘 몰랐습니다.

저는 친절한 임베디드 시스템 블로그(http://recipes.egloos.com)를 참고 했습니다.

(개인적으로 굉장히 좋은 사이트라 생각합니다... 못 믿으시겠다면 어서 방문을 ㄱㄱㄱ)

 

http://recipes.egloos.com/5009181 여기를 보면 심볼에 대한 정보가 굉장히 잘 나와있습니다.

심볼이란 Linker가 쓰는 기본 단위로써, Link를 한 후 에는 자신만의 주소를 갖게 되는 특별한 단위를 말한다. 

(이 부분이 젤 중요합니다.)

위에 진하게 되어 있는 곳을 보죠. 그 중 빨간색이 가장 중요한데요. "자신만의 주소를 갖게 된다" 이 부분 입니다.. 

우리가 C로 프로그램을 짜고 디버깅을 할 때 생각해 보죠. 우리는 그 변수에 할당된 값들을 볼 수 있습니다.

 이 때 이것들의 주소가 없다면? 당연히 볼 수 없겠죠?? 하지만… 우리는 모든 변수들의 값들을 볼 수 있습니다. 

왜냐? 주소를 갖고 있기 때문입니다. 지역변수 들은 비록 EBP, ESP로 할당된 스택 프레임 안에 들어 있지만. 

일단은 주소를 갖고 있죠? 근데 이것들은 심볼이라는 것이 없습니다. 위에서 보면 "자신만의 주소"를 갖게 되는 특별한 단위라고 했는데 왜 심볼이 없냐 하면… 이 지역변수 주소는 "자신만의 주소"는 아니죠? 스택 프레임은 각 함수마다 할당되었다 사라졌다 합니다. 그 주소는 여러 변수에 의해서 계속 쓰이게 됩니다. 그래서 지역 변수는 "심볼이 없다"라고 볼 수 있겠네요.


이 분은 Symbol을 Global이라고 부르십니다(왠지 교주 찬양하는 것 같네요 -_ -;;). Global 은 프로그램이 시작하고 끝날 때까지 없어지지 않는 것들을 말하죠? 거기에 해당되는 것들이 뭐뭐 있을 까요? 함수, 전역변수, static 변수가 있죠? 위에서 말한 것 처럼 자신만의 주소를 갖게 되는 것도 이런 Global 밖에 없습니다. 나머지는 전부 stack, heap이죠…. 할당 되고 해제 되는…


자자 계속 할게요. Symbol의 이름은 그 Symbol이 갖는 메모리 영역의 시작 주소를 가리키는 Linker만의 pointer라고 하네요. 우리가 디버깅 할 때 VS에서는 자동으로 pdb 파일이 생성되죠?


(모른신다고 하면 안됩니다. 여기 증거가ㅋㅋ)


이때도 symbol의 이름이 사용된다고 합니다. 또한 우리가 C, CPP 파일을 컴파일 하면 object file(이 녀석은 소스 파일마다 생성됩니다.)


이 생성되는데 이 안에는 Linker를 위해서 symbol table을 놔둔다고 합니다. 여기 안에는 source code에 의해서 참조되는 symbol들의 이름과 위치 정보가 들어 있으며, 다른 파일에 정의되어 있는 symbol정보를 쓸 경우에는 그 정보가 해당 file에 없기 때문에 그 object 파일 안에 있는 symbol table은 완전하지 못하다고 하네요. 이런 불완전한 symbol들은 linker에 의해서 처리하여 다른 파일에 있는 symbol을 연결하여 사용할 수 있도록 만든다고 합니다. 이 symbol 정보들은 메모리에 올라오는 것이 아니며…. 오직 linker만이 이 정보들을 쓴다고 하네요. 그리고 binary(윈도우는 PE, 리눅스는 elf)로 만들어 질 때 이 symbol들을 주소로 모두 변환한다고 합니다. (네 그래서 native code안에는 symbol 정보가 없습니다.)

 

여기까지가 제가 공부한 내용이네요. 요약해서 뭔 말인가 하면. 이 symbol정보들은 global 한 정보들을 말하며 실제 실행 파일 안에는 들어가 있지 않다. 왜냐면 linker만 사용하기 때문에 그리고 실행파일로 만들 때 object file 안의 symbol 들을 모두 주소로 변환하니깐. 이제 좀 이해가 되기 시작하네요…(감사합니다 히언님ㅋ)

 

Bloger: moltak.net

'Programming > 이것저것' 카테고리의 다른 글

x86 Register  (0) 2010.04.30
어셈블리어 점프 명령어  (0) 2010.04.29
IL Code에 심볼 정보가 포함되는 이유  (0) 2010.04.24
초기화 하지 않은 메모리  (0) 2010.04.16
[Design Pattern] Singleton Pattern  (2) 2010.04.16

이제 심볼이란 것이 무엇인지 정확이 알았으니…

IL Code에 왜 심볼 정보가 포함되는지 알아 봐야죠??

저번 시간에 Native Code에 왜 심볼정보가 포함되지 않는지를 봤었죠??

(못봤으면 참고: http://moltak.net/entry/Symbol이란)

간단히 설명하자면 심볼은 linker가 쓰는 것으로 binary가 생성되면서 심볼정보는 다 지운다고 했었습니다.

(정확히 말하면 모두 주소로 변환)

그래서 C언어를 어셈으로 보면 알아 먹기가 힘들었죠.

하지만 IL Code는 안에 심볼정보가 포함되어 있기 때문에 원래 짠 코드 그대로 볼 수 있습니다.

 

(참고: 쩔철이네 블로그)

 

처음 심볼이 뭔지 제대로 알지도 못할 때 진 MVP인 철에게 물었습니다.

어째서 IL코드에는 심볼정보가 포함되는 거야? 하구요. 철은 범용적인 것 보다는 .NET에 특화된 말을 했습니다.

(철이 말: 즉.. .Net에서는 이런 "언어간 상호 운영성"을 위해서 CLS가 존재하고, CLR은 이에 기인하여 생성된 IL코드를 기반으로 명령을 수행한다는 것이지요..

   

여기서 서로 다른 언어에서 동일한 Type이나 기능이지만 언어간에 서로 다른 형태의 Keyword를 사용할 수 있기 때문에..

IL코드의 생성이 필요하게 되었고, 이렇게 서로 다른 Keyword를 사용하는 언어간 동일한 동작을 보장하기 위해 어떤 동일한 명령으로 변환시키기 위해서 "IL코드에 심볼들이 포함 될 수 밖에 없었다."라는 것이 제가 내린 결론입니다.)

 

네…. 맞는 말인 것 같지만… 너무 복잡하네요. 쉽게 풀어서 설명해보죠.

 

다음 내용들은 ezbeat(http://ezbeat.tistory.com/182)블로그를 참고했습니다.

(모르는게 나오면 지인들의 힘을 빌리는 것이 참…. 편하고 좋더군요 ㅋㅋ)

 

자자 이제 정리해보죠. 사실 참 쉬운 것들이었습니다.

제가 자주 사용하는 C, C++은 Native Code를 생성해 내게 됩니다. 이게 뭐냐 하면 하드웨어에 종속되어 있는 코드입니다. 바로 어셈블리어죠.

위에 있는 그림처럼 처음 보는 사람은 절대 그 내용을 알 수 없는 내용들이 가득 차게 됩니다.

 

하지만 .NET, Java 같은 경우는 좀 다릅니다.

이것들이 만드는 코드는 하드웨어에 종속되어 있는 코드가 아닌 플랫폼에 종속된 코드를 만들게 됩니다. 바로 IL 코드입니다. 여기서 플랫폼이란 .NET Framework나 JVM이 되겠네요.

그리고 이 플랫폼들을 거쳐서 Native Code가 튀어나오게 되는 것입니다. 그리고 이 언어들은 한줄 한줄씩 컴파일되면서 실행되는 JIT(Just In Time) 컴파일을 하게 됩니다.

실행이 되는 순간에 동적으로 컴파일이 되어야 한다는 것입니다.

근데 컴파일을 하려면 결국 무엇이 필요하냐 면… 네 맞습니다. 바로 Symbol이 필요하죠. 그래서 IL 코드에는 Symbol 정보가 필요합니다.

자 이제 IL 코드에는 왜 심볼정보가 필요한지 아시겠죠??

 

간단히 말하자면… 실행이 되어야 하니까 필요합니다. 하하하하 쉽네요. ㅋㅋ

 

 

Bloger: moltak.net

'Programming > 이것저것' 카테고리의 다른 글

어셈블리어 점프 명령어  (0) 2010.04.29
Symbol  (0) 2010.04.24
초기화 하지 않은 메모리  (0) 2010.04.16
[Design Pattern] Singleton Pattern  (2) 2010.04.16
typeid 연산자  (1) 2010.04.15

1. WDK - Windows Vista RTM 을 다운 받아 설치

   

2. http://www.hollistech.com/Resources/ddkbuild/ddkbuild.htm 에서 ddkbuild 를 받아 압축을 풀고 vs .net 이 참조 가능한 패스에 복사한다.( C:\Program Files\Microsoft Visual Studio .NET 2005\Vc7\bin

3. DDKBUILD 에게 사용할 DDK version 을 알려주기 위해 약간의 편집을 해야 한다. ( 설치한 DDK 경로 설정 )

   

4. 프로젝트 생성 -> 메이크 파일을 선택

    

5. 디버그 구성 구성 설정에서 그림과 같이 설정.

   

6. 참고로 드라이버는 일반 어플리케이션과는 달리 debug build/release build 라고 하지 않는다. 
Debug build checked build
Release build free build

    

7. Visual Studio .Net의 intellisense 기능활용하기.

lib\wxp, inc\ddk, inc\api 폴더추가.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18
힙이나 스택에서 초기화를 안하면 뭔 값이 들어갈까?? 
마소에서 마음데로 정해 줬겠지만..ㅋㅋ
그래서 검색해봤다.

0xcccccccc : 초기화 되지 않은 지역 변수
0xcdcdcdcd : 초기화되지 않은 힙에 할당된 메모리
0xdddddddd : 힙에서 free된 메모리
0xfeeefeee : 힙에서 free된 메모리
0xfdfdfdfd : 힙에 할당된 메모리의 초가 범위(할당된 메모리의 양 끝 )
이런 비밀이 있었다.


'Programming > 이것저것' 카테고리의 다른 글

Symbol  (0) 2010.04.24
IL Code에 심볼 정보가 포함되는 이유  (0) 2010.04.24
[Design Pattern] Singleton Pattern  (2) 2010.04.16
typeid 연산자  (1) 2010.04.15
enum 문자열  (0) 2010.04.09
디자인 패턴에 대해 잘 알지는 못하지만... 예전에 열심히 공부해보려 했던 때가 있습니다.
디자인 패턴을 공부하시다 보면 아시겠지만 우리가 봉착한 문제를 유연하고 멋있게 해결합니다.
그 중에 제가 가장 잘 사용하는 것이 이 Singleton Pattern 입니다.

싱글톤 패턴의 정의는 아래와 같습니다.
소프트웨어 엔지니어링 영역에서의 singleton은 객체지향 프로그래밍 시 클래스가 단 하나의 사건, 즉 단 하나의 인스턴스만을 갖도록 하는 패턴이다.  이 패턴은 주로 중요한 자원을 관리하고자 할 때, 다수의 인스턴스가 생성되지 않도록 제한하기 위해서 사용한다.  예를들어, 한번에 하나의 인스턴스만이 DB에 연결되도록 설정할때 사용할 수 있다.

여러개의 인스턴스가 생성되면 안되는 것들을 하나만 생성되게 막는 것입니다. 
일단 어떻게 사용하시는지 보시죠.

저는 어제 올렸던 KSocket을 계속 발전 시켜 나갈 것입니다.

일단 헤더파일을 보시죠.
아래와 같이 instance를 하나 선언하고 가장 중요한 것은 생성자, 파괴자를 private로 선언하는 것입니다.
아무데서나 마음대로 사용할 수 없도록.
생성자 파괴자는 이제 static 함수에 의해서만 호출 될 수 있겠죠??

그리고 아래와 같이 인스턴스를 초기화 시켜주고 인스턴스 생성자, 인스턴스 파괴자 함수를 만들어 줍니다.
간단하고 명쾌하네요. 

하지만 클래스를 만들 때마다 위 처럼 안에 함수를 생성해야 한다는 것이 너무 귀찮고 안좋아 보입니다.
그래서 아래 처럼 템플릿으로 만들었습니다.
위 블로그를 가시면 알겠지만 굉장히 간결하게 짜 놓은 것을 볼 수 있네요.
조금만 보시면 쉽게 아실 겁니다.


사용은 m_KClientSocket = KSingleton< KSocketClient >::getInstance(); 이렇게 하시면 됩니다.
하지만 위 코드는 문제점이 있죠. 생성자, 파괴자는 인스턴스 생성 함수에 의해서만 호출 한다는 것이 깨져 버렸습니다. 
이것은 다음에 해결하도록 하겠습니다.

그럼 모두들 즐프 하세요 ^^/

'Programming > 이것저것' 카테고리의 다른 글

IL Code에 심볼 정보가 포함되는 이유  (0) 2010.04.24
초기화 하지 않은 메모리  (0) 2010.04.16
typeid 연산자  (1) 2010.04.15
enum 문자열  (0) 2010.04.09
ASCII Table  (0) 2010.04.05
다른 분들도 이 연산자를 사용하는지 모르겠지만... 저는 오늘 첨 알았네용ㅠㅠ
프로그래밍을 하던 중 인스턴스에 따라서 분기를 결정해야 했습니다. 평소 하던 방법은 문자열을 넣거나 nType이라는 타입 정수를 넣어서 그것에 맞춰서 해줬죠..
하지만 오늘 검색해보니 C++에서 C#과 같은 타입 비교 연산자가 있더군요;;
놀랐습니다.ㅋㅋ
아~~~주 좋습니다. ㅋㅋ


그래서 비교 코드를 아래 처럼 바꿀 수 있었죠.

아래는 skyarro라는 아이디를 쓰시는 블로그에서 퍼왔습니다.
결과 화면입니다.



모두 즐프요~~ㅋㅋ

'Programming > 이것저것' 카테고리의 다른 글

초기화 하지 않은 메모리  (0) 2010.04.16
[Design Pattern] Singleton Pattern  (2) 2010.04.16
enum 문자열  (0) 2010.04.09
ASCII Table  (0) 2010.04.05
사용자 정의 exception (1)  (0) 2010.03.21
복잡한 design module과는 다르게 굉장히 심플합니다. ㅋㅋㅋ
다들 해보시길 ㅋㅋㅋ

결과:


소스:



Bloger: moltak.net

오늘 SOC설계 시간에 배운 FSM입니다. 교수님이 그려주신 그림에 따라 설계하고 코드를 작성했습니다.
VerilogHDL 실력이 날이 갈 수록 늘어나고 있습니다. ㅋㅋ
기분이 좋군요. ㅋㅋ


위 그림이 기본 그림입니다. 괄호 안의 숫자들은 제가 사용하는 Spartan3의 포트 번호인데요. 이 코드를 갖고 ISE에서 Synthsesize 하면 됩니다. ㅋㅋ


위 그림이 기본 알고리즘인데요. 굉장히 간단하게 생겼습니다.
Accelerate와 Brake를 보고 상태에 따라 속도를 올리거나 줄이게 됩니다.




이 코드에서 가장 중요한 것은 OneShot Signal 인데요. 만약 사용자가 버튼을 클릭하게 되면 그 시간은 몇초 정도 되겠죠. ns로 따지면 엄청난 시간입니다. 그것을 단 한클럭만 하게 바꾸는 것이 OneShot Signal 이구요.


위 그림이 OneShot Signal을 나타내는데요. Acc를 버튼으로 가정하면 됩니다. 지금 클럭에 비해 굉장히 길게 입력이 되고 있죠?? 하지만 AccOneShot은 딱 한 클럭 만큼만 나타나고 있는데요. 그걸 가능하게 하는 것이 Acc_1과 Acc_2입니다. 이것들이 버퍼로 작동하는데 Propagal Delay(스펠링맞나??;;;)에 따라 한클럭 뒤에 값이 나오게 되죠. 이 값들을 저장해서 나중에 AND 연산을 취하게 됩니다.(아래 소스가 있습니다.) 그러면 위와 같이 AccOneShot Signal이 딱 튀어 나오게 되죠. ㅋㅋ 어렵습니다;;




위 소스가 OneShot Signal을 만드는 소스입니다. 자 공부 합시다. 공부 공부ㅋㅋㅋ


Bloger: moltak.net

아래 챕터 처럼 다 했다면 다 성공했다.

이젠 Flash에 쓸 차례다. 혹시 전원을 뽑아 봤나? 뽑으면 알겠지만.. 걍 죽는다.ㅋ

프로그램 다 사라짐ㅋ 처음에 엄청 어이없었다. ㅋㅋ

하지만 Flash 메모리에 쓰지 않았으니 사라지는게 당연하겠지 라고 생각하고 있다.

암튼 시작~

 

Flash에 쓰려면 PROM File로 포멧을 변경해야 한다. 위 그림처럼 PROM File Formatter를 더블 클릭하자.

위 그림처럼 메뉴가 뜨는데 나도 잘 모르지만 위 처럼하면 그냥 된다.

위 그림 처럼 Next를 누르다가 파일 한번 선택해 주고 또 Next를 누른다. 중요한것은 마지막 화면인데 화면창이 Add Device라고 쓰여져 있는게 보이나?? 다른 장치가 있으면 추가한다던데 해본적이 있어야지ㅋ 그냥 NO를 선택하자.

 

이젠 단순히 그림을 보고 따라가면 된다. 블로깅은 여기서 마치겠다.ㅋㅋ

 

+ Recent posts