函式庫的概念很簡單,當我們在寫程式時,會呼叫到許多函式 (Function),但這些函式是怎麼運作的,我們並不想讓他人知道。譬如說,有一些系統廠在Release SDK的時後,一些驅動程式的程式碼,並不會完整的Release出來,就會以函式庫的方式來做Release。
函式庫分為兩種型態,一種是靜態函式庫,附檔名為*.a (archives),相當於Windows下的*.lib (Libraries);
另一種則是動態函式庫 (或稱為共享函式庫),附檔名為*.so (shared object),相當於Windows下的*.dll (Dynamic-Link Libraries)。
靜態函式庫的缺點是,當我們在同一個時間執行很多的程序,他們都使用靜態函式庫中的相同函式,就會造成相同函數的程式碼重複佔用記憶體的狀況。事實上,在每個程式檔案中,也都複製了相同的函數程式碼。如此,同時浪費了許多記憶體和磁碟空間。
但,當一個程式引用動態函式庫的函數時,連結後的程序碼,並不會含蓋所呼叫的函數程式碼。直到程序被載入到記憶體執行時,才會去解決動態函式庫的函數和呼叫問題,就是在執行階段才將需要的部份載入記憶體。
所以,系統只需要準備一份動態函式庫,一次提供給眾多的應用程序,並且只佔用一份磁碟空間。
好,自己寫一個很簡單的範例,來記錄Linux下如何產生一個函式庫檔案:
需求非常簡單,我要寫2支函式─hello()和world(),在主程式 (main())中呼叫這兩支函數時,會直接秀出「Hello!! World!! 」,所以總共會有6個檔案,除了Makefile之外,其餘的檔案都非長地精簡:
Makefile:
# # File Name: Makefile # # CopyLeft (C) 2016; All rights reserved. # # Author: Pablo Picasso G. (PabloPicasso.G@gmail.com) # # Version: 0.0.1.build022216 # # Date: 2016 / 02 / 22 # # Description: # 1. This make file will include six files (*.c and *.h), # and it'll show "Hello!! World!! " # 2. # GCC := gcc CFLAGS := -c -g -DDEBUG OBJS := main.o hello.o world.o EXEC := main RM := rm -rf LIBS := libmain.a AR := ar -crv .PHONY: all all: $(EXEC) $(EXEC): main.o libmain.a @-$(GCC) -o $(EXEC) main.o -L./ -lmain $(LIBS): hello.o world.o @-$(AR) $(LIBS) hello.o world.o $(OBJS): %.o: %.c @-$(GCC) $(CFLAGS) $< -o $@ .PHONY: clean cleanall install print tar dist TAGS check test clean: @-$(RM) *.o cleanall: clean @-$(RM) $(LIBS) $(EXEC) install: print: tar: dist: TAGS: check: test:hello.h:
#ifndef _HELLO_H_ #define _HELLO_H_ #include <stdio.h> void hello(); #endifhello.c:
#include "hello.h" void hello() { printf("Hello!! \n"); return; }world.h:
#ifndef _WORLD_H_ #define _WORLD_H_ #include <stdio.h> void world(); #endifworld.c:
#include "world.h" void world() { printf("World!! \n"); return; }main.c:
#include "hello.h" #include "world.h" int main() { hello(); world(); return 0; }執行Makefile之后,就會產生main執行檔;也不難看出要產生函式庫檔案,就是透過ar -crv指令把hello.o和world.o壓成libmain.a檔案。
沒有留言:
張貼留言