동적 링크 라이브러리, 정적 링크 라이브러리와 실행 가능한 파일의 차이는 무엇입니까?

동적 링크 라이브러리(Dynamic Link Library, 줄여서 DLL)는 다른 응용 프로그램에서 공유할 수 있는 프로그램 모듈로 공유할 수 있는 절차와 자원을 봉인한다.동적 링크 라이브러리 파일의 확장자는 일반적으로 dll이며 drv,sys,fon일 수도 있습니다. 이것은 실행 가능한 파일 (exe) 과 매우 유사합니다. DLL에 실행 가능한 코드가 포함되어 있지만 단독으로 실행할 수 없고 Windows 프로그램에서 직접 또는 간접적으로 호출해야 한다는 차이점이 있습니다.
동적 링크는 정적 링크에 대한 것입니다.정적 링크란 호출할 함수나 과정을 실행 가능한 파일에 연결시켜 실행 가능한 파일의 일부분이 되는 것을 말한다.다시 말하면 함수와 과정의 코드는 프로그램의exe 파일에 있으며, 이 파일은 실행할 때 필요한 모든 코드를 포함한다.여러 프로그램이 같은 함수를 호출할 때 메모리에 이 함수의 여러 복사본이 존재하기 때문에 귀중한 메모리 자원을 낭비한다.동적 링크에서 호출된 함수 코드는 응용 프로그램의 실행 가능한 파일로 복사되지 않고 호출된 함수에 대한 설명 정보만 추가되었다(왕왕 위치 변경 정보).응용 프로그램이 메모리에 불러와 실행을 시작할 때만 Windows의 관리 아래 응용 프로그램과 해당하는 DLL 사이의 링크 관계를 맺을 수 있습니다.Windows는 호출된 DLL의 함수를 실행할 때 링크에서 생성된 재배치 정보에 따라 DLL의 함수 코드를 실행합니다.
일반적인 상황에서 만약에 한 응용 프로그램이 동적 링크 라이브러리를 사용한다면 Win32시스템은 메모리에 DLL의 복제품만 있다는 것을 보장한다. 이것은 메모리 맵 파일을 통해 이루어진 것이다.DLL은 먼저 Win32 시스템의 전역 스택으로 이동한 다음 이 DLL을 호출하는 프로세스 주소 공간에 비칩니다.Win32 시스템에서, 모든 프로세스는 자신의 32비트 선형 주소 공간을 가지고 있으며, 만약 하나의 DLL이 여러 프로세스에 호출된다면, 모든 프로세스는 이 DLL의 이미지를 받을 것이다.
프로그램 개발을 하는 친구들은 Lib과 Dll에 대해 잘 알고 있어야 한다. 이 두 가지에 대해 몇 군데는 기쁨과 근심이라고 할 수 있다. 좋아하는 사람들은 코드를 봉인해서 다른 사람이 표절하지 않도록 할 수 있다고 생각하고 싫어하는 사람들은 그것을 귀찮다고 생각하는데 왜 원본 파일을 직접 사용하지 않는가.특히 초보자는 Lib과 Dll의 관계와 사용에 대해 전혀 알지 못한다.
Lib은 정적 링크 라이브러리(static link library)라고 하는데 컴파일된 링크 기간에 사용되는 것으로 그 안에 원본 파일의 함수가 들어 있다.
Dll은 동적 링크 라이브러리(Dynamic link library)가 되어 프로그램이 실행될 때 동적 호출되고runtime에 사용되며 원본 파일의 함수 구현, DllMain 입구 함수와def 파일.
먼저 Lib 라이브러리에 대해 이야기해 봅시다. 상대적으로 사람들은 그것에 대해 dll보다 좀 익숙합니다.
Lib 라이브러리
Lib 라이브러리는 두 가지가 있는데 하나는 흔히 볼 수 있는 일반 Lib(static Lib)이고 사람들이 자주 다운로드하는 소스 코드를 컴파일하면 Lib과 dll이 생긴다. 그 중에서 Lib은 Dll의 부수품일 뿐이고 DLL에서 내보낸 함수 목록 파일일 뿐이며 Dynamic Lib이라고 부른다.
둘 다 이진 파일입니다. 둘 다 링크에서 호출된 것입니다. static lib의exe를 사용하면 직접 실행할 수 있고,dynamic lib의exe를 사용하려면 대응하는 dll가 필요합니다.다음은 static lib 파일을 생성하고 사용하는 방법을 보여 줍니다.
여기서 우리의 도구가 VS2005(포함) 이상의 버전이라고 가정하면 다른 도구는 모두 대동소이하므로 소개하지 않겠습니다.
1. win32 콘솔 프로젝트 구축
2. 응용 프로그램 설정 단계에서 정적 라이브러리 static Library 를 선택합니다.
3. 완성하면 된다(이곳은 가장 간단한 Dll에 대한 것일 뿐, Win32 Application의 방식은 조금 다르다)
이렇게 정적 Lib 라이브러리의 공사가 다 되었다.코드는 다음과 같습니다.
//////////////////////////////////////////////////////////////////////////
// Function.h
//////////////////////////////////////////////////////////////////////////

void Print();
//////////////////////////////////////////////////////////////////////////
// Function.cpp
//////////////////////////////////////////////////////////////////////////
#include "Function.h"

void Print()
{
	std::cout << "Hello world!" << std::endl;
}

컴파일하면 프로젝트 이름을 Lib 파일이 생성됩니다.
프로젝트 프로젝트 속성에 이 Lib 파일의 헤더 파일 디렉터리와 Lib 파일 디렉터리를 포함합니다.
헤더 디렉터리 포함 방법: 항목 속성(Alt + F7)-> 설정 속성-> C/C++ -> 일반-> 추가 포함 디렉터리, 당신의 Lib 라이브러리의 헤더 파일을 포함합니다. 절대 경로를 사용할 수도 있고 VS에서 매크로로 표시된 상대 경로를 사용할 수도 있습니다. 상대 경로를 사용하는 것을 권장합니다.
Lib 파일에는 항목 등록 정보(Alt + F7) -> 구성 등록 정보 -> 링크 -> 일반 -> 추가 라이브러리 디렉토리가 포함되어 있으며, 이 안에 Lib 파일의 경로를 기입하십시오.프로젝트 등록 정보(Alt + F7)-> 구성 등록 정보-> 링크 -> 일반-> 를 입력하고 Lib 파일의 이름을 입력합니다(예: Function).lib
이렇게 하면 너는 너의 코드에서 이렇게 사용할 수 있다.
#include 
#include 
#include "Function.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Print();
	system("pause");
	return 0;
}

이렇게 하면 Lib 라이브러리를 완전하게 생성하고 사용하는 예입니다.
물론 #pragma comment(Lib, "LibPath") 방법으로 Lib 파일을 호출할 수도 있습니다.
==============================================================
Dynamic Lib의 호출 방법은 Static lib과 완전히 일치하며, 유일한 차이점은 Dynamic Lib을 사용하여 컴파일된 프로그램을 실행할 때 해당 Dll 파일이 필요하다는 것입니다.앞에서 우리가 이미 말했다.
DLL
다음에 우리는 Dll의 문제를 잘 이야기합시다. Lib에 비해 Dll이 사용하는 주파수는 매우 높을 것입니다. 왜냐하면 당신의 프로그램이 실행되고 시스템이 실행되는 등은 모두 그것에 의존하기 때문입니다. MS도 이것 때문에 운영체제가 점점 좋아지기 때문입니다.
Dll은 사실 Exe와 거의 똑같다. 유일하게 다른 것은 Exe의 입구 함수식 WinMain 함수(console 프로그램은main 함수)이고 Dll은 DllMain 함수이며 다른 것은 완전히 같다.그래서 누군가는 Dll을 스스로 실행할 수 없는 Exe라고 놀린다.
Dll을 만드는 과정도 비교적 간단하지만, 유일하게 번거로운 것은 내보내기 함수 인터페이스를 정의해야 한다는 것이다.
Dll 프로젝트를 만드는 과정은 매우 간단합니다. win32 컨트롤러 프로젝트를 만들고 응용 프로그램이 설정한 단계에서'동적 라이브러리 다이나믹 리브레리'를 선택하면 완성할 수 있습니다.(이곳은 단지 가장 간단한 Dll에 대한 것일 뿐, Win32 Application의 방식은 조금 다르다)
내보내기 함수 인터페이스를 정의하는 방법은 다음과 같습니다.
1. 사용declspec 매크로
// dllmain.cpp :    DLL         。
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Fucntion.h
//////////////////////////////////////////////////////////////////////////

extern "C" __declspec(dllexport) void Print(void);
//////////////////////////////////////////////////////////////////////////
// Function.cpp
//////////////////////////////////////////////////////////////////////////
#include "Function.h"

void Print(void)
{
	std::cout << "[Dll] Hello world!" << std::endl;
}

여기에 우리의 프로젝트 이름이 Function이라고 가정하면, 컴파일하면 Function이 생성될 것이다.dll 및 Function.Dynamic lib(Dynamic lib), Dynamic lib은 앞서 설명한 바와 같이 여기서 더 이상 설명하지 않습니다.
Function.h 헤더 파일의
extern "C" __declspec(dllexport) void Print(void);

우리는 그 중의 함수의 명칭, 반환값, 매개 변수만 정확히 알면 된다.
extern "C"는 C 언어의 방식으로 이 함수를 컴파일해야 하며, C++ 프로젝트에서 함수 이름 오류가 발생하지 않도록 합니다. C++에 함수 재부팅이 있기 때문에 함수 이름이 컴파일된 후에 나타날 수 있습니다.Print@1형식그리고 이렇게 하면 C가 C++의 동적 링크 라이브러리를 호출할 수 있다;declspec(dllexport)이 표시하는 함수는 dll의 내보내기 함수 인터페이스입니다.
2. def 파일을 사용합니다. 인터페이스를 내보내는 방식과 유사하지만, 설명할 필요가 없습니다. 왜냐하면 이것은 전문적으로 def 파일을 정의하여 설명하기 때문입니다.
// dllmain.cpp :    DLL         。
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Fucntion.h
//////////////////////////////////////////////////////////////////////////

void Print(void);
//////////////////////////////////////////////////////////////////////////
// Function.cpp
//////////////////////////////////////////////////////////////////////////
#include "Function.h"

void Print(void)
{
	std::cout << "[Dll] Hello world!" << std::endl;
}
//////////////////////////////////////////////////////////////////////////
// Fucntion.def
//////////////////////////////////////////////////////////////////////////

EXPORTS
	Print

마찬가지로 Static Lib과 같은 현식 호출 방법은 dll도 현식 호출할 수 있다. 전제는 우리가 함수 이름, 반환 값, 매개 변수 목록을 잘 알고 있다는 것이다.
 
#include 
#include "Function.h"
#include 

int _tmain(int argc, _TCHAR* argv[])
{
    HINSTANCE hInstance  = LoadLibrary("Function.dll");
    typedef void(*_Print)(void);
    _Print printFunction;
    if (hInstance != NULL)
    {
        printFunction = (_Print)GetProcAddress(hInstance, "Print");
    }

    printFunction();
    FreeLibrary(hInstance);
    system("pause");
    return 0;
}

그럼요. 현식도 있고 자연도 있고 은식도 있어요. 이럴 때 Function.dll의 반생산물 Function.lib는 사용 방법이 정적 lib와 완전히 같아서 쓸모가 있습니다.
DLL 호출의 두 가지 방법은 각기 장점이 있다. DLL에서 함수 주소를 찾는 방법을 사용하면 함수의 형태가 변하지 않으면 함수를 수정해도 상관없고 Exe를 다시 컴파일할 필요가 없다. 새로운 DLL 파일을 복사하면 되고 대형 프로젝트에서 비교적 유연하게 사용할 수 있다.단점은 실례, 함수 포인터, DLL 불러오기, DLL 방출 등 과정을 정의해야 한다는 것이다.다이나믹 Lib의 방법을 사용하면 쉽게 이해하고 받아들일 수 있다는 장점이 있다(정적 라이브러리의 호출 방법과 유사하기 때문이다).단점은 DLL 프로젝트를 수정한 모든 것이 최신 Dynamic Lib을 사용하여 Exe를 다시 컴파일할 수 있다는 것이다.
 
요약:
DLL과 Lib은 각기 다르고 사용 상황도 각기 다르지만 최종적으로 프로젝트에서 어떤 방법이 좋은지, 어떤 유형의 라이브러리를 사용하는지 실천해야 한다. 어쨌든 모든 것이 수요에 따라 가장 좋다.

좋은 웹페이지 즐겨찾기