삽질의 현장/- 윈도우 시스템

#032_WIndow_System_DLL (1)

shovelman 2015. 9. 30. 21:09


안녕하세요 삽잡이입니다.


이번 시간에는 DLL에 대해서 알아보겠습니다.


라이브러리는 뭘까요? 바로, 기능 집합을 말합니다.

일반적으로 기능 집합과 형식집합이라고 부르는데,

기능집합은 함수 형태의 프로그램에서 부르고, 형식 집합은 객체 지향 형태에서 부릅니다.


이 라이브러리는 두 가지로 나뉘게 됩니다.

바로 정적 라이브러리 (static link library)와 동적 라이브러리(dynamic link library) 입니다.

그래서 동적 라이브러리를 줄여서 dll이라고 부르는 것입니다.

정적은 lib라고 부르고요...


왜냐, 예전에는 동적 라이브러리라는 개념이 없었기 때문에 

라이브러리라고 하면 정적 라이브러리 밖에 없었습니다.

그래서 lib로 사용하다가 동적 라이브러리라는 개념이 생기며 이를 dll로 불리기 시작한 것입니다.


정적 라이브러리는 Compile time이 될 때 결정이 됩니다.

그리고 동적 라이브러리는 Run time이 될 때 결정이 됩니다.


그러면 우리가 예를 들어 Swap.cpp, Print.cpp, Main.cpp 파일이 있다고 가정해봅시다.

이 파일들은 컴파일 과정을 거치면 각각 .obj 파일가 만들어지게 됩니다.

그리고 실행파일이 되기 위해서는 링킹 과정을 거쳐야 되는데

참고로 링킹 과정은 obj파일들이 결합되는 과정을 말합니다.

이 링킹 과정까지 거치게 되면 .exe 파일이 만들어지는 것입니다.


여기서는 임의로 App.exe 파일이라고 하겠습니다.


그런데, .exe파일에는 기본적으로 OS가 제공하는 lib가 들어가야합니다.

왜냐? 우리가 프로그램을 만들 때 OS가 제공하는 기능 없이 만들 수가 없기 때문이지요...

OS가 제공하는 기능은 우리가 구현한 것이 아닙니다.

그런데 이 기능을 App.exe에서 사용하기 위해서는OS가 제공하는 lib파일이 포함되어야되지 않겠습니까?

그래서 lib파일과 함께 링킹이 되어야 완전한 App.exe프로그램이 되겠지요...


아무튼... OS에서 제공하는 프로그램은 .lib에 있다는 사실은 변하지 않습니다...


obj 파일들을 임의의 sp.lib 파일로도 만들 수 있습니다.

즉, 하나의 묶음으로 라이브러리 파일을 만들 수 있게 되는 것이지요...

여기서 Swap.obj와 Print.obj 파일을 묶어서 임의로 sp.lib라고 부르겠습니다.


그러니까 lib는 오브젝트 파일의 묶음이라고 할 수 있습니다.

기존에 가지고 있는 명령어들을 컴파일이 완료한 바이너리 집합이라고 부를 수 있다는 것입니다.

즉, 컴파일이 완료된 바이너리 집합들을 라이브러리라고 부르며,

다시 말해서, 바이너리가 기능별, 형식별로 묶여져 있는 형태를 라이브러리라고 부를 수 있습니다.


그럼 이제 sp.lib와 main.obj 그리고 OS가 제공하는 lib 파일을 묶으면 APP.exe파일이 완성됩니다.

지금 APP.exe 파일은 실행되기 직전에 컴파일을 할 때 lib파일이 .exe파일에 묶여져 있다고해서 

정적 라이브러리라고 부르는 것입니다.

따라서 .exe파일에서 라이브러리를 떼고 싶어도 못 떼지요...


이럴 경우 단점이 있습니다.

파일을 계속 만들다보면 여러 실행 파일에 포함이 될 터인데,

굉장히 많이 사용하는 놈들이라면 실행파일마다 계속 포함이 될 것입니다.

장점은 뭐 .exe파일에 포함이 되있기 때문에 이를 사용하기 위해 부가적인 작업이 필요 없다는 것입니다.

결론은 정적 링크 라이브러리는 .exe파일에 포함된다는 것입니다.


그런데 OS가 제공하는 라이브러리는 엄청나게 클 것 같습니다.

엄청나게 기능이 많이 들어있고 보편적인 기능을 가지고 있으니까 말입니다...

그리고 모든 어플리케이션은 그 기능을 사용할 테인데...

각 어플리케이션 마다 이 라이브러리를 가지고 있다가는 메모리가 아작나겠습니다...

그리고 어플리케이션이 그 기능들을 다 쓸까요...

일부만 쓰겠지요... 메모리 낭비군요...


그래서 OS가 제공하는 기능 혹은 굉장히 굉장히 큰 기능, 많은 프로세스들이 

공용적으로 사용하는 기능들을 프로세스에 묶어서 사용하면 안됩니다.

위의 이유로 말입니다...


그래서 DLL이 만들어 진 것입니다. 

즉, 공유하는 메모리, 실행 시간에 로드되서 사용가능하다 해서 DLL!


동적 링크 라이브러리는 OS 라이브러리와 관련성이 있습니다.

절대 정적으로 사용되지 않기 때문이죠...


DLL의 역할은 .exe에 들어가지 않는다는 것입니다.

그렇다면, 되면 main.obj에 있는 함수들을 어떻게 쓸까요... 정보가 없는데...


어플리케이션이 물리 메모리에 할당 되면

예를들어... CreateWindow 함수를 호출하려 했는데 없다면,

CreateWindow를 포함하고 있는 공용 DLL을 물리 메모리에 띄우고 

그 공유 메모리가 뜨게되면 사용하고자하는 프로세스의 가상 주소에 매핑 시키게 됩니다.

그렇게 되면 매핑된 놈을 불러다가 쓰게 되는 것입니다.

마치 원래 내가 가지고 있는 것처럼 쓸 수 있다 이것입니다.


또 다른 어플리케이션을 생성했다고 해봅시다.

그러면 또 DLL의 메모리를 매핑 시키는 것입니다.

진짜 내용물은 하나인데, 여러놈들이 원래 자기것처럼 쓰는 것이지요...

참고로 해당 영역은 명렁어들이 자리 잡은 Read Only의 영역입니다.


이와 같이 사용하게 되면 아무리 많은 프로세스가 DLL을 사용하더라도 

딱 하나만 필요하게 되는 이점이 있습니다.

그리고 여러 프로세스가 해당 DLL을 쓰게 되면

reference count만 증가가 되는 것이지요... 안쓰면 감소하고...

마치 usage count와 같이 말입니다. reference count가 0이 되면 OS에서 가져오게 됩니다.


여기서 근데 문제가 두가지 생깁니다.

우선, 첫째로 CreateWindow와 같은 함수의 정보 자체가 없는데,

정보도 없으면 컴파일을 못할 것인데 어떻게 되냐...


그리고, 메모리상에 DLL이 없으면 로드시키고 매핑을 해야하는데...

즉, 어떻게 연결 확인을 할것인지가 문제라는 것입니다.


우선 DLL을 만들면 그 DLL은 서비스입니다.

DLL은 어플리케이션들이 사용하게 되는데, DLL은 서버가 되고 어플리케이션은 클라이언트가 되는 것입니다.


위에서 예시로 든, 

Swap과 Print 기능을 DLL에 넣어서 클라이언트에 가져다 쓰려는데 

클라이언트에 해당 정보가 포함되어있지 않겠지요... (DLL을 쓰는 목적 자체를 생각해보세요...)

그런데 정보가 없으면 컴파일을 할 수 없게 되지 않습니까...


그래서 서버의 기능 즉, DLL 기능을 클라이언트에 가져다 쓰는데 두가지 방법을 제공합니다.


이 기능들에 대해서는 다음 시간에 알아보도록 하겠습니다.


이상 삽잡이였습니다!



'삽질의 현장 > - 윈도우 시스템' 카테고리의 다른 글

#033_WIndow_System_DLL (3)  (0) 2015.10.01
#033_WIndow_System_DLL (2)  (0) 2015.09.30
#031_WIndow_System_힙(Heap)  (0) 2015.09.30
#030_WIndow_System_메모리 맵 파일  (0) 2015.09.30
#029_WIndow_System_IPC_파이프(2)  (0) 2015.09.30