라이브러리, 동적, 정적
함수를 비유할 때, 도구, 부품이라고 했었다. 여기서 도구는 Library(라이브러리)와 SDK가 있다고 했는데, 이것이 CRL이였고, printf()함수도 여기에 속한다. 여기서 함수를 모아서 하나의 덩어리로 만든 것이 Library고, 이것을 끌어다가 printf()같이 쓰는 것이다. SDK는 약간 다르다. 아이폰, 안드로이드, 윈도우 등, 각각의 플랫폼 제조사에서 제공해주는 함수들이다. 사실 제조사가 제공해줄 때, 형태를 정해서 만들어 주는데, 그것이 라이브러리(Library)다.
라이브러리는 동적(Dynamic, 다이나믹)라이브러리와, 정적(Static, 스태릭)라이브러리가 있다. 여기서 동적라이브러리는 강의에서 다루지 않는다. 동적라이브러리는 DLL이라고 해서, 함수포인터도 들어가게 되는 라이브러리로 알아두자.
정적 라이브러리
정적 라이브러리는 ~.obj(목적파일)처럼 생겼다. 프로그램, HelloWorld.c(소스파일)가 있다고 하면, 소스파일을 프로그램으로 바꾼다면, HelloWorld.obj(목적파일)로 바뀌고, 결국 프로그램인 HelloWorld.exe(실행파일)이 된다. 그런데, 정적라이브러리를 만든다고 설정해주고, 아예 다른 소스파일인(소스파일이 묶여있을 때 쓰는 extern과는 다르게, 다른 프로젝트로 소스파일이 분리되어있다) LibTest.c를 만들고, LibTest.obj로 하면, LibTest.exe로 나오지 않고 LibTest.Lib로 나온다. 그럼, 아까의 HelloWorld.obj와 LibTest.Lib를(오브젝트 파일처럼) 붙여서 링크해서 HelloWorld.exe를 만들 수 있는 것이다.
이때 .Lib에서는 함수의 정의가 담기게 되기에, HelloWorld.c에서는 함수의 원형만 가지고 함수를 굴릴 수가 있는 것이다. 이때 .Lib는 정적라이브러리인데, 말 그대로, 목적파일처럼 .obj파일에 붙어서 기존 소스파일의 함수를 대신 정의해준다.
이때, HelloWorld.c에서는 맨 위에 #prama comment(lib, "LibTest.lib")와 같이 “정적 라이브러리의 이름. 확장자”꼴로 작성해주면 함수의 정의를 정적라이브러리에서 Call해서 쓸 수 있게 된다. (이때 #prama comment는 19장에 배울 ‘전처리기’에 대한 내용이다. 별 중요한 의미는 아니니 우선은 그렇다고만 알아두자.)
그리고 LibTest.h로 함수를 선언해준다. 여기서 중복으로 불렸을 때 방지하는 #pragma once(이것도 ‘전처리기‘에서 배울 내용이다)도 위에 붙여주고, #prama comment(lib, "LibTest.lib")를 붙인 다음, 함수를 원형만 선언 해준다.
.lib로 정적라이브러리가 있다면, 그와 같은 .h로 함수의 선언도 해주는 것이 세트로 붙게 되는 것이다.(둘이 세트로 움직인다)
사실 이런 내용을 다루면서 배우는 점은, 헤더파일이 라이브러리의 함수를 쓰는 것을 알려주는 역할인 걸 이해하면 좋다. 다시 한 번 정적라이브러리와 함께 헤더파일의 의미도 챙기자.