LIB / DLL 차이점

반응형

link :  http://loger1000.springnote.com/pages/1626606

 

정적 링크라이브러리(Static Link Library)와 동적 링크라이브러리(Dynamic Link Library)

  -정적링크라이브러리-
 프로그램에서 특정 함수를 사용할려구 할 때 라이브러리 파일을 project-->setting-->Link-->Object/library modules에
 추가를 해주면 해당함수에 대한 기능이 구현된 부분이 실행파일에 덧붙여 지는 것이다.
 
#pragma comment(lib, "opengl32.lib")렇게 써주는 것두 같은 방법이다.

   -동적링크라이브러리-
 dll파일이 독립적으로 실행파일 밖에서 존재하다가 필요시에만 링크되는 형태
 1.메모리와 하드디스크를 절약할 수 있다.
 2.프로그램 실행속도가 빨라질 수 있다.
 3.프로그램이 모듈화 됩니다.


이런 차이가 있다. 그리고 dll에는 두가지 종류가 있다. 


 -일반 DLL과 확장 DLL이다.-
 일반DLL ===>C++,파스칼,비베등 다른 환경에서 사용할 수 있는 범용DLL이다.
             단점은 외부에서 사용되기 때문에 C함수의 형태로 만들어져야 한다.클래스나 오버로딩된 함수등의
             C++의 특징들은 일반 DLL의 내부에서 자유로이 사용될 수 있으나,다른 프로그램에서 사용될 수 
             있도록 라이브러리 형태로 만들 수는 없다.
 확장DLL ===>클래스나 오버로딩된 함수도 모두 라이브러리 형태로 외부의 프로그램에 제공할 수 있다.
             단점은 Visual C++(MFC)에서만 사용

  ::Visual C++(MFC)로 개발하는 프로젝트의 일부를 모듈화할 때는 확장 DLL,
    범용적인 라이브러리만들 때는 일반 DLL

  -MFC AppWizard(dll)을 선택시-

 * 위에 두 개는 일반dll 세 번째것은 확장 dll입니다.
        Preprocessor definition:_AFXEXT,_AFXDLL


 * (위에) 일반 dll은 정적링크(MFCxx.dll등의 파일이 필요없는거) MFC관련 DLL이 자신의 DLL에 결합되기 때문에 배포시

         자시만 Preprocessor definition:_USRDLL


 * (아래것은) MFC관련 DLL이 필요하게 됩니다. 이렇게 하면 필요한 함수나 기능들이 MFCxx.dll과 연결이 되므로
        5분의 1정도의 용량이 줄어듭니다. 쉽게 기본적으로 제공되는 MFC DLL을 사용하는냐 안하느냐 문제죠...
        Preprocessor definition:_USRDLL,_AFXDLL 

 

Preprocessor definition 는 컴파일러 커맨드 라인에 정의하는 전처리어로[Project->Setting...]메뉴를 선택하여 출력된 다이얼로그의 C/C++탭에서 볼 수 있다.
 _WINDLL :컴파일러에게 현재 프로젝트가 DLL임을 알려준다.
 _USRDLL:컴파일러에게 작성할 DLL이 일반 DLL임을 알려준다.
 _AFXDLL:컴파일러에게 작성할 DLL이 MFC DLL에 동적으로 연결됨을 알려준다.
 _AFXEXT:컴파일러에게 작성할 DLL이 확장DLL임을 알려준다.

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

동적 라이브러리 만들기...

정적 라이브러리는 Lib..동적 라이브러니는 DLL로 구분을 합니다(확장자가)

구동상의 차이는 정적 라이브러리는 컴파일시 실행파일에 포함되고
동적 라이브러리는 실행파일이 라이브러리에 필요한 작업 혹은 데이터가 있을때
라이브러리파일을 읽어와서 실행한다는 차이점이 있죠.. 

동적이건, 정적이건 이미 컴파일 되서 나오기 때문에 개발 시간은 물론이고
디버깅에도 매우 유리하다고 합니다.(단 라이브러리에 버그가 없을때 이겠죠 ㅎㅎ)

 일단 라이브러리를 만들때는 라이브러리가 호출한 프로그램에게 어떤 함수를
제공하고 있는지, 다른 말로 이 함수는  외부에서 사용할수 있다는 키워드를 넣어줘야 합니다..
또 묵시적 연결을 사용하는 실행파일에선 무슨 함수를 쓰겠다는 선언을 해 줘야 하죠.(나중에 설명)

그런 작업을 하는 키워드가  __declspec(인수) 원형;입니다..
보통 원형에 __declspec(인수)란것이 들어간다는 점이 틀린 정도이구요..
인수에는 원형이 어떤 기억분류(?)인지 표준화 한다고 하네요..
간단히 라이브러리 만들때 제공하는 것들은 dllexport
실행파일에서 무슨 라이브러리를 쓰겠다고 선언할땐 dllimport
해당 스레드에서만 가용할수 있는 변수일땐 thread
이정도만 알아두면 기본적으로 쓰는데는 지장없을거 같네요...
그외에도 naked란 인수가 하나 더 있는데 이건 어셈으로
가상 디바이스 드라이버 만들때 사용한다고 하므로 패스 --;

 그외에는 일반 함수 작성하는것과 똑같습니다...
일단 보통 프로그램처럼 엔트리 포인트(main이나 Winmain)이 필요는 없습니다..
하지만 필요하다면 만들어줄수도 있죠(필요없을땐 간단하게 툴이 만들어 주는거 같습니다)
DLL의 엔트리 포인트는 DllMain입니다..
여기에 3개의 인수가 전달받게 되는데 HINSTANCE, DWORD, LPVOID 타입를 전달해 줍니다..
이 함수가 실행되는건 4가지 조건이 발생했을때 호출이 되는데
DWORD에 호출 사유를 전달받으면 그에 따른 처리를 해주면 됩니다..

DLL_PROCESS_ATTACH - DLL이 로드 될 때
DLL_PROCESS_DETACH - DLL이 삭제 될 때
DLL_THREAD_ATTACH - DLL을 사용하는 프로세스에서 스레드를 생성할때
DLL_THREAD_DETACH - DLL을 사용하는 프로세서에서 스레드가 종료될때

각각의 값에 따라 처리를 해주면 됩니다..형식은 다른 윈도우 프로시저하고 비슷하죠.. 
dll를 빌드하면 dll파일과 lib파일이 생성되게 됩니다. 

이렇게 만든 dll을 사용할수 있는 방법은 크게 두가지입니다..

묵시적 연결과 명시적 연결...

묵시적 연결은 컴파일할때 로드할 라이브러리를 미리 정의 시키는 방법입니다..
위에서 썼듯 묵시적 연결을 할때는 사용할 함수를 __declspec(dllimport) 원형;
으로 미리 지정해 주어야 합니다..

또 dll 빌드시 생성된 lib를 링커에 추가시켜 줘야 합니다..
보통 비주얼 스튜디오에선 프로젝트 속성->링커 쪽에 링크옵션 추가하는 부분 찾어서 넣어주면 됩니다..
그후엔 일반 함수 쓰듯이 그냥 사용해 주면 됩니다..

명시적 연결은 프로그램이 자체적으로 읽을 라이브러리를 지정해서 로드하는 방법입니다.
명시적 연결에는 기본적으로 3가지 함수가 사용되는데
라이브러리 로드할때 사용하는 LoadLibrary(읽을 파일) - 읽은 파일의 핸들을 리턴
라이브러리에서 함수를 읽는 GetProcAddress(라이브러리 핸들, 함수명) - 함수 포인터 리턴
읽은 라이브러리를 더이상 사용 안할서 해제할때 쓰는 FreeLibrary(라이브러리 핸들) - bool 리턴
명식적 연결을 사용할때는 기본적으로 함수 포인터를 사용하는 방법을 알고 있어야 합니다..

사용법은 함수 포인터로 함수를 호출하는 방식이 묵시적 연결하곤 좀 틀리죠..
참고로 LoadLibrary로 dll을 읽을때 윈도우는 해당 dll의 카운트를 증가시킵니다..
FreeLibrary로 dll를 해제할땐 카운트는 하나 줄이죠..
결국 카운트가 0이되어야 해당 dll이 메모리에서 삭제되므로 이 둘은 쌍으로 사용해 줘야
OS의 메모리 낭비를 막을수 있답니다..

 이런식으로 작성한 실행파일은 반드시 해당 DLL이 있어야 실행이 가능합니다..
당연히 DLL이 없으면 실행되지 않습니다^^;

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

<첫번째 답변>

 링크에서의 차이점입니다.
링크라는 것에 대해서 개념이 부족하시면 이해하시기 힘드신 부분입니다.
링크라는 것은 실행파일을 만들때, 컴파일된 결과를 이어주는 것입니다. 

예를 들어서 a.cpp 파일에서 FX() 라는 함수를 불러쓰는 것이 있는데, 이 함수는 다른 곳에 만들어져 있어도 컴파일이 되죠. 
FX() 라는 함수를 실제로 사용하기 위해서는 FX() 함수가 실제로 있어야합니다. 
이 실제의 FX() 함수를 프로그램 실행파일 만들 때 연결(link)해주는 것이 바로 스태틱 링크(static link)입니다.  l
ib 파일을 이용한 것이죠.

그러나 실행파일을 실행중에 실제 함수 FX() 함수를 연결해주는 방법은 런타임링크(Run time link)
또는 다이나믹 링크(dynamic link)라고 합니다. 
이 때 사용하는 것이 바로 dll 파일이죠.

 스태틱 링크를 하였을 경우에는 exe 파일만 배급해도 실행이 되지만,
런타임링크를 했을 때에는 반드시 exe 파일과 함께 dll 파일도 배급해야합니다. 

런타임링크의 장점은 공통된 모듈의 경우 dll로 사용함으로써 메모리 절약뿐 아니라,
메모리 로드에 의한 시간절약 등의 효과가 발생합니다. 
그러나 버전 관리 등 여러가지 문제가 역시 발생할 수 있죠. 

dll로 컴파일하였을 경우 lib 파일도 같이 생성이 됩니다. 
이 때 lib에 있는 내용은 dll을 로딩하고 링크하는 역할이 들어가있습니다.
 

<두번째 답변>

우리가 프로그램을 컴파일을 하면 실행 파일이 생성됩니다.
이때 컴파일의 단계를 보면 크게 2 부분으로 나누어져 있습니다. 

1. 컴파일
2. 링크 

1 번에서는 프로그램상의 오류들을 검사하고, 각 명령어를 기계어 코드로변환하죠.
컴퓨터는 기계어밖에 읽지 못합니다.
그래서 님께서 만드신 프로그램코드를 기계어 코드로 변환하죠.
그리고 2번에서는 님께서 만든 기계어 코드에서 님께서 사용한 함수들의
실행코드(기계어코드)를 찾습니다.
물론 님께서 만든 함수도 있고, 시스템에서 제공한 함수도 있습니다.
시스템에서 제공한 함수는 Librarry 파일이 따로 있기 때문에
해당 Library 에 가서 실행 코드를 가져와서 님께서 호출한 부분에Copy 합니다.
그리고 님께서 만든 함수가 있다면 그 함수를 찾아서 해당 부분에 Copy 합니다.
이때 실행 코드가 없으면 에러가 나겠죠. 

이렇게 크게 두부분으로 처리됩니다.
링크때 함수의 실행코드를 님의 실행코드에
붙이게 되는데 이 방법을 static link Library 라고 합니다.
즉, 링크단계에서 필요한 모든 함수의 코드를 찾아서 붙이는 방법이죠.
이 방법이 좋은것은 어떤 PC 에 실행 코드를 갖다놔도 실행이 됩니다.
즉, Library 파일이 따로 없더라도 실행 파일 자체가 모든 Library 를 가지고 다니기 때문이죠. 

하지만 DLL(Dynamic Link Library) 는 링크때 실행 코드를 Library 에서 가져오지않습니다.
단지 이부분에 오면 어떤 함수를 어디에서 사용한다는 정보만 들어갑니다.
정작 실행할때 해당 파일(DLL 파일) 을 열어서 실행코드를 가져와서 사용합니다.
즉, 컴파일 할때 필요없다는 얘기 입니다.

실행 할때 꼭 필요합니다.
그래서 실행 파일과 DLL 파일이 같이 움직여야 합니다.
다른  PC 에 실행파일을 Copy 할때 DLL 파일도 같이 Copy 해야 실행 됩니다.
좀 안좋게 느껴지죠 ?
하지만 좋은 점도 있습니다.
만약 어떤 수정사항이 생기면 static link library 같은 경우는 소스를 수정해서 다시 배포해야 합니다.
하지만 Dynamic Link Library 같은 경우는 수정되는 부분이 DLL 함수내에 있다면
DLL 파일만 수정해서 DLL 파일만 배포하면 됩니다.
그래서 수정사항이 생길수 있는 부분을 DLL 파일로 구현을 해서 혹 수정사항이
생기면 DLL 파일을 다시 배포하는 경우가 많습니다.

 자, 이해가 되시나요 ?
그래서 어떤 프로그램을 실행하면 DLL 파일이 없다는
메시지를 본적이 있으시죠 ? 바로 이런 이유 때문입니다.

그리고 Windows Update 가 가끔 일어 나는데 이렇게 DLL 파일만 수정되는 경우도 많습니다. 
안그러면 모든 파일을 배포해야 하는데 그 크기가 엄청크겠죠. 

모두 장단점이 있으면 잘 생각하셔서 만드시길 ...
제 생각엔 그렇게 크지 않은 업무면 static link library 로 괜찮을 듯 ...
DLL 이 그렇게 좋지만 않습니다 ....

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

dll, lib 는 코드를 모듈로 분산시킬때(?) 보통 쓰겠죠

dll 과 lib 의 차이점이라면 dll 은 다른 프로그램에의해 코드가 공유가 된다는 이점이 있겠고 (여러 프로그램이 같은 dll 을 사용한다는 뜻, 다만 공유메모리를 사용하지 않으면 독립적으로 메모리공간이 존재합니다) lib 는 실행화일과 합쳐져서 그 실행화일만 코드를 사용하겠죠

lib 은 헤더가 제공되어야 하겠고 dll 같은경우는 헤더를 제공하던지 함수형과 인자 정보를 별도로 제공해 사용될 수 있습니다

보통 우리가 c언어로 코딩을 할때 여러가지 기능을 루틴으로 분리합니다. 보통 그 루틴들을 함수로
만들어 놓고 쓰죠... (dll, lib)

이 함수들을 메인 실행파일에 포함되지 않고.... 다른 파일로 분리해 놓은게 dll 입니다.
즉 메인 실행파일에 이 함수의 몸체부분은 들어가 있지 않습니다.

메인 실행파일이 실행시에 해당 dll파일을 로드하며 필요한 함수들을 호출하여 이용합니다.
lib로 컴파일하면 메인 실행파일에 함수들의 몸체가 들어가는 형태입니다.

[장점]

dll :

- 메인 실행 파일의 사이즈가 작아진다.
- dll 에 있는 함수들을 다른 곳에서도 호출하여 쓸수 있으므로 재사용성이 증대된다.

lib:

- 속도가 좀 빠르다
- 코드하기가 간단하다.

[단점]

dll:

- 좀 사용이 복잡하다. (단, low 레벨로 코딩시; Lib를 쓰는것처럼 편하게 돼 있기도 합니다)
- 속도가 lib에 비해 느릴수 있다. (dll 파일도 찾아야 하고.. 로드하고 함수 포인터 위치도 얻어야 하고)

lib:

- 실행 파일의 크기가 커진다.
- 함수의 재사용성이 소스레벨에서만 가능하다.


그리고 둘다 헤더 파일을 제공해야 합니다.
단, dll의 경우 헤더 없이도 호출 가능하지만 좀 어려워요...

'Study > C++' 카테고리의 다른 글

boost::has_trivial_assign  (0) 2011.04.10
메모리맵 파일  (0) 2011.04.09
How to convert std::string to TCHAR*  (0) 2011.01.06
문자열 비교할때 대소문자 구분없이 하기.  (0) 2010.12.03
dllimport, dllexport  (0) 2010.11.15
TAGS.

Comments