2008. 10. 3. 22:28

#pragma

#pragma 는 #로 시작하는 전처리구문 지시자 중 컴파일러에 종속적인 명령으로, 
컴파일러에 특정한 옵션 명령을 내리기 위해 사용하는 데요, 

컴파일러에 종속적이기 때문에 컴파일러를 변경했을 경우 실행을 보장하지 못합니다. 

대표적인 #pragma 명령 중에서 once나 pack, comment(lib, *) 등이 있는데 이는 각각 
컴파일러에 

1 once : 해당 소스가 단 한번만 포함되게 한다(여러 번 인클루드 되는 것을 
컴파일러 차원에서 막아줍니다) 

2 pack : 변수 정렬을 인위적으로 변경시킨다(보통은 4바이트로 지정되어 있습니다) 

3 comment(lib, *) : comment로 사용할 수 있는 명령은 여러 개 있는데, 
그중 가장 대표적인 것이 lib 으로, 해당 라이브러리를 링크시켜준다 

과 같은 명령을 내립니다. 



api나 mfc의 구분과 관계없이 해당 컴파일러에서 사용하는 명령이랍니다

 

 

 

MSDN에 있는 내용
code_seg
#pragma code_seg( ["section-name"[,"section-class"] ] )

Specifies a code section where functions are to be allocated. The code_seg pragma specifies the default section for functions. You can, optionally, specify the class as well as the section name. Using #pragma code_seg without a section-name string resets allocation to whatever it was when compilation began.

==========================================================

실행파일에는 코드영역과 데이터영역이 구분되어 있다는 것은 아시지요.
┌───────┐
│                     │
│                     │
│   데이터영역   │
│                     │
│                     │
├───────┤
│                     │
│                     │
│     코드 영역   │
│                     │
│                     │
└───────┘
이런 식의 그림은 아마 어디선가 많이 보셨을겁니다.(그림이 깨지네요.편집할 땐 제대로 보였는데...)
이런 영역을 section이라고 하지요. 위의 설명에 나오는 section이라는 용어가 이것입니다.
실제로 데이터 영역과 코드 영역외에도 exe나 dll에는 여러 section을 포함할 수 있습니다.
이건 dumpbin이라는 툴로 살펴볼 수 있습니다.
제 컴(Windows XP)에서 dumpbin c:\windows\notepadd.exe 를 해 보았더니

2000 .data
2000 .rsrc
7000 .text

이렇게 나오는 군요.

여기서 .data에는 초기화된 데이터가 .rsrc에는 리소스들이, .text에 코드가 들어갑니다.
이러한 .data, .rsrc, .text 등은 일반적으로 정해져 있는 것들입니다.
위 MSDN의 설명에 있는 section-name이라는 것이 바로 .data, .rsrc, .text 등을 뜻하는 겁니다.
즉, #pragma code_seg( .data ) 처럼 사용한다는 거지요.
그리고 Specifies a code section where functions are to be allocated.라는 설명은 
Specifies a section where functions or data or etc. are to be allocated. 이렇게 이해하면 더 나을 듯 하네요.

그런데 이런 정해진 이름말고도 사용자가 새로운 영역을 정할 수 있습니다.

#pragma data_seg("Shared")
DWORD g_dwThreadIdPMRestore = 0;
HWND g_hwnd = NULL;
#pragma data_seg()

이런 식으로 하면 g_dwThreadIdPMRestored와 g_hwnd가 디폴트 데이터 섹션인 .data에 배치되지 않고,
Shared라는 이름으로 만들어진 섹션에 배치되는 것입니다.

=====================================================

#pragma data_seg(...)가 사용되는 곳은 
dll간의 데이터 공유를 위해 사용될 수 있습니다.
그리고 그 외에 어디서 사용되는지는 저도 아직 본 적이 없어서 잘 모르겠습니다.

======================================================

참고로 위의 내용은 "어드밴스 윈도우 NT"를 참고해서 작성했습니다.
이 책은 지금 나오지 않고 이 책의 새 버전이 "Programming Applications for Microsoft Windows"(Jeffrey Richer 저)로
번역판도 나와 있습니다.