36. Library의 constructor와 destructor, NULL Library
이번 장에서는 Library의 constructor(생성자)와 destructor(소멸자)에 대해 배운다.
CONSTRUCTOR
새 라이브러리 모듈을 만든다.
$ vi UefiLessonsPkg/Library/SimpleLibraryWithConstructor/SimpleLibraryWithConstructor.inf
---
[Defines]
INF_VERSION = 1.25
BASE_NAME = SimpleLibraryWithConstructor
FILE_GUID = 96952c1e-86a6-4700-96b0-e7303ac3f92d
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
LIBRARY_CLASS = SimpleLibrary | UEFI_APPLICATION
CONSTRUCTOR = SimpleLibraryConstructor
[Sources]
SimpleLibraryWithConstructor.c
[Packages]
MdePkg/MdePkg.dec
UefiLessonsPkg/UefiLessonsPkg.dec여기에 CONSTRUCTOR에 생성자 함수라는 이름의 명령문을 추가했다. 이것이 언제 실행되는지 알기 위해 Print 명령문을 추가해보자.
이제 새 라이브러리를 사용하는 다른 애플리ㅇ케이션을 만들 필요가 없다. 이제는 단순히 UefiLessonsPkg/UefiLessonsPkg.dsc에서 라이브러리 설정을 변경하면, SimpleLibraryUser가 새로운 라이브러리 버전으로 다시 컴파일된다.
다른 부분은 건드리지 않아도 괜찮다.
만약 이 앱을 빌드하고, OVMF를 실행하면, 다음과 같은 화면이 나올 것이다.
생성자를 사용하는 라이브러리의 예로는 UefiBootServicesTableLib 라이브러리가 있다. https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
우리는 이를 이전 장들에서 모두 사용해 보았으니, 한 번 사용해보도록 하자.
사실, 이 라이브러리가 가지고 있는 것은 생성자일 뿐이다.
이 라이브러리의 작동 방식을 이해하려면, *.c 및 *.h 파일을 확인해보자. https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c
이 라이브러리는 UEFI의 main 부분에 대한 바로가기와 같은 몇 가지 전역 변수를 설정한다. 라이브러리 생성자가 Main 앱 코드이전에 실행되므로, 이 라이브러리를 사용하여 gImageHandle/gST/gBS 모든 부분에 접근할 수 있다.
DESTRUCTOR
마찬가지로, 생성자와 소멸자가 모두 존재하는 SimpleLibrary의 다른 버전을 만들 수 있다.
UefiLessonsPkg/UefiLessonsPkg.dsc의 끝부분을 바꾸는 것을 잊지 말도록 하자.
이제 애플리케이션을 실행하면, 처음과 끝에 모두 문자열을 출력할 것이다.
생성자와 소멸자가 모두 있는 라이브러리의 예로, DebugLibConstructor.c를 살펴보자.
https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c
이 라이브러리는 생성자에서 CreateEvent를 사용하고, CloseEvent를 사용하여 소멸자에서 닫는다.
NULL Library
이미 언급했었다시피, OVMF는 Shell 앱자체를 포함하고 있다. 컴파일을 위해 OVMF 패키지 DSC(OvmfPkgX64.dsc) 파일에는 다음 문자열이 포함되어 있다.
여기서 일부 라이브러리 클래스에 NULL 클래스가 있음을 알 수 있다.
NULL 라이브러리 클래스는 개념적으로 "anonymous library, 익명 라이브러리"이다. 모듈이 라이브러리의 함수를 직접 호출하지 않더라도 모듈에 코드를 정적으로 연결할 수 있다.
앱에서 라이브러리 API를 호출할 필요 없이 라이브러리 생성자/소멸자기능만 필요한 경우 유용할 수 있다. https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
해당 파일을 보면, 이 모듈의 생성자가 shell에 명령을 추가하는 데 사용된다는 것을 알 수 있다.
위의 방법은 Shell command support를 다른 모듈로 분할하는 꽤나 괜찮은 방법이다. 이 기능을 사용하면 필요한 command support를 통해 Shell 이미지를 쉽게 컴파일할 수 있다.
Last updated