WinCNT

Dynamic-Link Library(DLL) 본문

게임 프로그래밍(학습 내용 정리)/시스템 프로그래밍

Dynamic-Link Library(DLL)

WinCNT_SSS 2022. 5. 23. 14:27

정적은 복사본, 동적은 링킹만 함

(파일 안에 포함되지 않음)

 

명시적, 암묵적이 다르다

암묵적은 실행 시에 링킹됨

명시적은 프로그래머가 원하는 타이밍에 링킹함(교체 등의 컨트롤 가능)

 

https://docs.microsoft.com/ko-kr/windows/win32/dlls/about-dynamic-link-libraries

 

Dynamic-Link 라이브러리 정보 - Win32 apps

동적 연결을 사용하면 모듈이 로드 시간 또는 런타임에 내보낸 DLL 함수를 찾는 데 필요한 정보만 포함할 수 있습니다.

docs.microsoft.com

 

DLL을 로드하는 모든 프로세스는 해당 가상 주소 공간에 매핑한다

즉, 각각의 프로세스에 DLL이 로드된 가상 주소 공간은 다를 수 있다!

 

DLL 내의 전역 및 정적 변수는 DLL 을 공유하는 프로세스 간의 통신에 활용이 가능한가?

불가능하다

https://docs.microsoft.com/ko-kr/windows/win32/memory/memory-protection

 

메모리 보호 - Win32 apps

프로세스에 속하는 메모리는 프라이빗 가상 주소 공간으로 암시적으로 보호됩니다.

docs.microsoft.com

 

두 프로세스 모두 실제 메모리에 페이지의 자체 인스턴스가 있다

따라서 한 프로세스가 공유 물리적 페이지에 쓰고 다른 프로세스에서는 변경한다

시스템에서는 이러한 인스턴스 중 하나가 페이지를 수정할 때까지 동일한 실제 페이지를 공유할 수 있다

 

프로세스 간의 메모리 공유를 위해서는 다른 기법이 존재한다

메모리 매트 파일 등등

 

DLL의 장점

어플리케이션의 기능 확장

DLL은 프로세스의 주소 공간동적으로 로드될 수 있기 때문에

어플리케이션이 수행 중이더라도 수행해야 할 작업이 결정되면

해당 작업을 수행할 수 있는 코드를 로드할 수 있다

 

프로젝트 관리의 단순화

개발 과정에서 여러 그룹이 서로 다른 작업을 수행하고 있는 경우라면

DLL을 사용함으로써 프로젝트 관리를 좀 더 쉽게 수행할 수 있다

 

리소스 공유의 촉진

윈도우 API가 대표적인 예시

 

그 외에도 지역화 촉진, 플랫폼 차별성 해소 특수한 경우(Hook, ActiveX, ...) 등이 있다

 

DLL과 프로세스 주소 공간

DLL은 단순히 다른 어플리케이션이나 DLL에서 호출하는 함수들의 집합인 모듈을 구현하는 소스 코드로 구성된다

즉, 다른 어플리케이션에서 사용할 수 있는 독립적인 함수들로 이루어져 있다

메시지 루프를 처리한다거나 윈도우를 생성하는 등의 작업은 일반적으로 DLL로 만들지 않는다

 

C/C++ 런타임 라이브러리와 DLL

단일의 주소 공간은 하나의 실행 모듈과 다수의 DLL 모듈로 구성되어 있다

이 중 일부 모듈은 C/C++ 런타임 라이브러리정적으로 링크하고 있을 수도 있고

또 다른 모듈은 C/C++ 런타임 라이브러리동적으로 링크하고 있을 수도 있다

또한 C/C++ 런타임 라이브러리를 사용하지 않은 모듈(C/C++로 개발되자 않은 경우)도 있을 수 있다

 

즉 단일 주소 공간 내에 C/C++ 런타임 라이브러리가 여러 번 로드될 수 있다는 뜻이며,

이러한 사실을 잊을 경우 문제가 생기기도 한다

//////////////////////////////////////////////////////////////////////////
// 실행 파일
//////////////////////////////////////////////////////////////////////////
VOID EXEFunc()
{
	PVOID pv = DLLFunc();
	free(pv);
}

//////////////////////////////////////////////////////////////////////////
// DLL 파일
//////////////////////////////////////////////////////////////////////////
PVOID DLLFunc()
{
	return (malloc(100));
}

위는 DLL 함수 내에서 할당한 메모리 블록을 실행 파일의 함수 내에서 삭제하고 있는 코드이다

위의 코드는 정상 작동할까? 답은 '모른다'이다

 

만일 실행 파일과 DLL이, 동적 C/C++ 런타임 라이브러리를 사용한다면 정상 작동할 수도 있지만

둘 중 하나의 모듈이 정적 C/C++ 런타임 라이브러리를 사용한다면 free 함수를 호출할 때 문제가 생길 것이다

 

이에 대한 해결책으로는 메모리를 할당하는 함수를 제공하는 모듈

반드시! 메모리를 삭제하는 모듈도 함께 제공해야 한다

//////////////////////////////////////////////////////////////////////////
// 실행 파일
//////////////////////////////////////////////////////////////////////////
VOID EXEFunc()
{
	PVOID pv = DLLFunc();
	DLLFreeFunc(pv);
}

//////////////////////////////////////////////////////////////////////////
// DLL 파일
//////////////////////////////////////////////////////////////////////////
PVOID DLLFunc()
{
	return (malloc(100));
}

BOOL DLLFreeFunc(PVOID pv)
{
	return (free(pv));
}

 

SSS