윈도우 라이브러리 파일

이 글은 마이크로소프트 **윈도우 라이브러리 파일**들에 대한 설명이다. 마이크로소프트 윈도우 운영 체제는 dll이라고 알려진 라이브러리를 지원하는데, 이것들은 복사본 하나만 메모리에 올라와도 여러 프로세스에서 사용될 수 있는 코드 라이브러리이다. 이 문서는 현재 윈도우에 포함된 코드 라이브러리들의 개요를 제공한다.

## 내부 구성 요소
이 단락에서 설명하는 라이브러리 파일들은 대부분의 프로그램에서 직접적으로는 사용되지는 않는다. 하지만 대부분의 프로그램들에서 사용되는 다른 라이브러리들이 의존하는 라이브러리이다.

### Hal.dll
하드웨어 추상화(HAL)는 **Hal.dll** 안에 구현되어 있다. HAL은 다양한 플랫폼들의 다양한 방식들이 구현된 많은 함수들을 구현한다. 운영 체제의 다른 구성 요소들은 이것 덕분에 다른 모든 플랫폼들의 실제 구현 방식을 알지 못해도 이 함수들을 사용하여 일관성을 제공받을 수 있다.

예를 들면, APIC(Advanced Programmable Interrupt Controller)를 사용하는 머신의 인터럽트에 반응하는 것은 다른 것들과 상당히 다르다. HAL은 다양한 칩셋들을 통해 모든 종류의 인터럽트들은 통일시킨 함수를 만들어 준다.

HAL은 커널 주소 영역에 적재되어 커널 모드로 실행되기 때문에 HAL 내부의 루틴들은 응용 프로그램에 의해서 직접적으로 호출될 수 없다. 그리고 어떤 사용자 모드 API들도 직접적으로 HAL과 연동될 수 없다. 그렇기 때문에 HAL은 실행 프로그램과 커널 그리고 커널 모드 장치 드라이버에게 주로 서비스를 제공한다. 비록 대부분의 하드웨어의 드라이버들이 다른 파일들에 포함되어 있지만 .sys나 소수의 중요한 드라이버들은 Hal.dll에 컴파일된다.

PCI와 PCI 익스프레스 같은 커널 모드 장치 드라이버들은 입출력 포트와 자기 드라이브의 레지스트리에 접근하기 위해 직접적으로 HAL의 루틴을 호출한다. 다양한 플랫폼들이 그들만의 다양한 연산들에 의한 구현을 요구하기 때문에 드라이버들은 HAL 루틴을 이용한다. HAL은 각 플랫폼들에게 맞는 적절한 연산들을 구현한다. 이로써 같은 드라이버에서 실행될 수 있는 파일은 (같은 종류의 CPU를 가진다면) 모든 플랫폼에서 사용될 수 있고, 드라이버 소스 파일은 모든 아키텍처에서 이식이 가능해진다.

x86 시스템의 경우, 설치 프로그램에는 여러 다른 종류의 HAL 파일들이 존재한다. 윈도우는 설치 시 현재 플랫폼에 어떤 것이 적절한가를 결정하고 하드 드라이브에 복사해 놓고, 필요한 경우에는 Hal.dll에 renaming을 시킨다. 선택하는 기준은 다음과 같다. ACPI 호환가능한 BIOS의 존재, APIC의 존재, 그리고 여러 프로세스들이 존재하는가와 사용 가능한가. x86-64과 아이테니엄 플랫폼에서는 각각의 CPU에 가능한 단 하나의 Hal.dll이 존재한다.

### NTDLL.DLL
NTDLL.DLL은 네이티브 API를 노출시킨다. 네이티브 API는 (Win32나 다른 API 하위 시스템에의 지원 없이) 운영 체제의 사용자 모드 구성 요소에 의해 사용되는 인터페이스이다. 대부분의 이 API들은 **NTDLL.DLL에 구현되어 있으며**, ntoskrnl.exe(및 그 변종)의 윗면이다. 그리고 이 라이브러리 내부에서 노출되는 대부분의 심볼들은 **Nt**를 접두어로 갖는다. 네이티브 API들은 또한 KERNEL32.DLL에 의해 노출되는 커널 API들이나 베이스(base) API들을 구현하기 위해 사용된다. 참고로 대부분의 윈도우 응용 프로그램들은 NTDLL.DLL을 직접적으로 호출하지 않는다.

이 라이브러리와 직접적으로 링크된 응용 프로그램을 **네이티브 응용 프로그램**(native application)이라고 하며, 이것은 Win32 하위 시스템이 사용 가능해지기 전인 윈도우 시작 전에 실행되기 위해 존재한다. 예를 들자면 Win32 하위 시스템 프로세스(csrss.exe)의 호출 같은 경우인데, csrss.exe 프로세스가 존재하기 전에는 어떤 Win32 프로세스도 생성될 수 없기 때문이다.

네이티브 응용 프로그램이 .exe 확장자를 가지고 있다고 해도, 사용자나 Win32 또는 다른 하위 시스템에 의해 실행되는 것은 아니다.

Win32 응용 프로그램들과 달리 네이티브 응용 프로그램은 커널 런타임 코드(ntoskrnl.exe) 안에 생성되며, 그러므로 다른 진입 지점(Entry Point)을 갖는다. (**NtProcessStartup** 등이 그것인데, **(w)(Win)MainCRTStartup** 같은 Win32 응용 프로그램에서 볼 수 있는 것과는 다르다.) 이것은 그들의 명령 줄 전달인자(argument)를 인 메모리 구조에 대한 포인터를 통해서 얻는다. 또한 **Rtl** 힙(heap) API를 통해 자신의 메모리를 관리하고, NtTerminateProcess (ExitProcess가 아닌)를 통해 리턴한다. 네이티브 응용 프로그램에 링크된 보통의 라이브러리는 nt.lib인데, 이것은 네이티브 응용 프로그램의 시작 코드(startup code)를 포함하며, C 런타임이 Win32 응용 프로그램에 시작 코드(startup code)를 제공하는 것과 비슷한 방식이다.

비록 대부분의 API들이 문서화되어 있지 않지만, 네이티브 응용 프로그램은 윈도우 DDK를 사용하여 만들 수 있다. 많은 바이러스 검사 소프트웨어와 유틸리티 프로그램이 이것들을 이용하여 만들어진다.

## Win32 API
이 단락에 있는 라이브러리들은 각각 다양한 Win32 API들을 구현하는 부분 집합이다.

### KERNEL32.DLL
KERNEL32.DLL은 메모리 관리, 입출력 명령, 프로세스와 스레드 생성, 그리고 동기화 함수들 같은 대부분의 Win32 베이스(base) API들을 응용 프로그램에 내보낸다. 대부분의 것들이 (NTDLL.DLL에 의해 내보내진) 상응하는 네이티브 API를 호출함으로써 KERNEL32.DLL의 내부에 구현되어 있다.

### GDI32.DLL
GDI32.DLL은 그래픽 장치 인터페이스(GDI) 함수들을 노출시키는데, 이것들은 디스플레이나 프린터에 출력되는 원시적인 드로잉 함수들을 수행하는 역할을 한다. 응용 프로그램들은 GDI 함수들을 낮은 수준의 드로잉을 위해 직접적으로 호출한다.

### USER32.DLL
**USER32.DLL**은 윈도우 USER 구성 요소를 구현한다. 윈도우 구성 요소는 창이나 메뉴 같은 윈도우 사용자 인터페이스의 표준 요소들을 생성하고 다룬다. 그러므로 프로그램들에게 그래픽 사용자 인터페이스(GUI)를 구현할 수 있게 해준다. 프로그램들은 창 생성이나 관리, 그리고 창 메시지 받기 등을 수행하기 위해 윈도우 USER에서 함수들을 호출한다.

GDI에 관한 많은 USER32.DLL 함수들은 GDI32.DLL에 의해 내보내진 것들이다. 어떤 종류의 프로그램들은 또한 GDI 함수들을 직접적으로 호출하여 낮은 수준의 드로잉을 수행하기도 한다.

### COMCTL32.DLL
**COMCTL32.DLL**는 파일 오픈, 저장, 상태바 같은 다양한 종류의 윈도우 표준 컨트롤을 구현한다. 이것은 이런 UI 요소들을 위한 윈도우를 만들고 관리하기 위해 USER32.DLL와 GDI32.DLL에서 함수들을 호출한다.

## 다른 API들
### SHSCRAP.DLL
**SHSCRAP.DLL**은 객체 연결 삽입(OLE) 메커니즘의 한 부분이다. 이것은 셸 스크랩(scrap) 파일들에 대한 지원을 구현한다. (OLE이 가능한 응용 프로그램의 선택된 콘텐츠를 바탕 화면으로 드래그할 때 자동으로 생성됨) 또한 오브젝트 패키저(Object Packager)를 통해 생성할 수도 있다. 이때는 다른 OLE이 가능한 응용 프로그램에 드래그할 수 있다.

이 기능은 윈도우 비스타부터 보안 향상과 일반적으로 사용되지 않은 기능을 삭제하기 위해 제거되었다. 스크랩 (.shs) 파일들은 코드부터 시작해서 다양한 내용을 저장할 수 있어서 바이러스로 사용되어 왔다. 이 기능은 윈도우 XP의 DLL에서 레지스트리 엔트리를 복사해서 다시 복구할 수 있다.

## 런타임 라이브러리
### MSVCRT.DLL, MSVCPP.DLL, CRTDLL.DLL
**MSVCRT.DLL**은 비주얼 C++ 버전 4.2부터 6.0까지의 마이크로소프트 비주얼 C 런타임 라이브러리(C++ 라이브러리로는 **MSVCPP.DLL**)이다. 이것은 이 버전의 비주얼 C++로 컴파일된 프로그램과 C와 C++ 프로그램이 요구하는 일반적인 라이브러리 함수 집합들을 제공한다. 이것들은 문자열 처리와 메모리 할당 그리고 C 스타일 입출력 호출같은 것들을 포함한다.

이것은 윈도우 95 OSR2 버전 이후로 계속되어 왔으며, 이전 버전은 대신 **CRTDLL.DLL** 라이브러리였다. 오래된 윈도우 버전에서는 MSVCRT.LL에 링크된 프로그램의 호환되는 복사본을 System32 폴더 안에다가 설치하게 했었는데, 이것은 DLL 지옥로 이어지게 된다.

4.0 이전의 비주얼 C++과 7.0 이후 버전은 각각의 버전마다 다른 이름들을 사용했다(MSVCR20.DLL, MSVCR70.DLL, MSVCR71.DLL, MSVCP110.DLL 등). 응용 프로그램들은 적절한 버전의 것들을 설치하도록 요구되었다.

마이크로소프트 비주얼 C++ 런타임은 윈도우에 포함되어 있다. 설치된 운영 체제보다 최신에 나온 런타임들은 **비주얼 C++ 재배포 가능** 패키지에서 구할 수 있다.

레퍼런스와 디버깅을 위한 런타임 라이브러리의 소스 코드들은 비주얼 C++에 포함되어 있다.(예를 들면 `C:\Program Files\Microsoft Visual Studio 11.0\VC\crt\src`안에).

이 런타임 라이브러리는 비주얼 C++로 쓰인 프로그램들에 의해 사용된다. 또한 MinGW 컴파일러에서도 사용된다. 몇몇 컴파일러들은 자신들만의 런타임 라이브러리를 가지고 있다.

### 다른 런타임 라이브러리
* **ATL*.DLL** - 액티브 탬플릿 라이브러리(Active Template Library)
* **MFC*.DLL** - 마이크로소프트 파운데이션 클래스 라이브러리(Microsoft Foundation Classes)
* **MSVBVM60.DLL** - 비주얼 베이직 6.0 가상 머신 (대신 비주얼 베이직 닷넷 프로그램에는 닷넷 프레임워크가 필요함)

### 닷넷 프레임워크 라이브러리
C#, 비주얼 베이직 닷넷, C++/CLI 그리고 .NET 언어로 쓰인 프로그램들은 닷넷 프레임워크를 요구한다. 이것은 많은 라이브러리들과 (예를 들면 **mscorlib.dll** &mdash; Multilanguage Standard Common Object Runtime Library, 이전의 마이크로소프트 공통 오브젝트 런타임 라이브러리(Common Object Runtime Library)) 어셈블리라고 불리는(예를 들면 **System.Windows.Forms.dll**) 많은 라이브러리를 가지고 있다.

## 같이 보기
* 윈도우 NT 아키텍처
* 윈도우 NT 시작 프로세스

* 윈도우 API
* 동적 링크 라이브러리

## 각주

## 외부 링크
*  API calls list - USER32.DLL - Tips for using the User API Client Library with Visual Basic
*  API calls list - KERNEL32.DLL - Tips for using the Kernel API Client Library with Visual Basic
*  Native API reference
*  Unofficial website that documents most of the Native API methods 
*  Retrieving the KERNEL32.DLL base address

분류:마이크로소프트 API
분류:윈도우 구성 요소