上篇文章呈現了linux下動態庫的乙個簡單實現,其介面按通用的方式匯出,測試程式可以直接呼叫,本篇展現乙個匯出函式列表的方式,可以通過函式列表實現對介面的呼叫
標頭檔案
/*
@ file name: calc.h
@ author: hw
@ mail: [email protected]
@ created time: 2015-07-01 14:42:00
*/#ifndef _calc_h_
#define _calc_h_
#ifdef __cplusplus
extern "c"
calc_funclist;
typedef calc_funclist* calc_funclist_ptr;
typedef calc_funclist_ptr* calc_funclist_ptr_ptr;
int getfunclist(calc_funclist_ptr_ptr ppfunclist);
typedef void (*get_funclist_ptr)(calc_funclist_ptr_ptr ppfunclist);
#ifdef __cplusplus
} #endif
#endif
原始檔
/*
@ file name: calc.c
@ author: hw
@ mail: [email protected]
@ created time: 2015-07-01
14:39:26
*/#include "calc.h"
#ifdef __cplusplus
extern "c"
intsub(int a, int b)
static calc_funclist m_functionlist =
;int getfunclist(calc_funclist_ptr_ptr ppfunclist)
#ifdef __cplusplus
}#endif
測試程式1
/*
@ file name: test1.c
@ author: hw
@ mail: [email protected]
@ created time: 2015-07-01
17:50:16
*/#include
#include
#include "calc.h"
int main()
測試程式2
/*
@ file name: test2.c
@ author: hw
@ mail: [email protected]
@ created time: 2015-08-25 09:49:41
*/#include
#include
#include
#include "calc.h"
#define libname "./libcalc.so"
int main(int argc, char *argv)
pfunc = dlsym(handle, "add");
printf("test add [ 1+2 = %d]\n",pfunc(1,2));
pfunc = dlsym(handle, "sub");
printf("test sub [ 1-2 = %d]\n",pfunc(1,2));
ppfunclist = (get_funclist_ptr)dlsym(handle, "getfunclist");
ppfunclist(&pfunclist);
printf("test add [ 1+2 = %d]\n", pfunclist->fnadd(1,2));
printf("test sub [ 1-2 = %d]\n", pfunclist->fnsub(1,2));
dlclose(handle);
return
0;}
makefile
cc = gcc
cflags =
ldflags = -shared -fpic
inc = -i.
libs = -ldl
dll = libcalc.so
objs = calc.o
.phony
:all
all:lib test1 test2
lib:
$(objs)
$(cc) $(
ldflags) -o $(
dll) $(
objs)
$(objs):%.o:%.c
$(cc) $(
cflags) $(
inc) -c $< -o $@
test1:
$(cc) -o test1 test1.c $(
dll)
test2:
$(cc) -o test2 test2.c $(
libs)
clean:
rm -f *.o
rm -f $(
dll) test1 test2
編譯動態庫及測試程式
$ make
檢視動態庫的匯出符號
$ nm -d libcalc.so
00000414
t getfunclist
w _jv_registerclasses
00001590 a __bss_start
w __cxa_finalize
w __gmon_start__
00001590 a _edata
00001598 a _end
00000464
t _fini
000002bc t _init
000003fc t add
00000407
t sub
可以看到,介面getfunclist add sub都被成功匯出,這兒我們將add sub介面也一併匯出了,也可以只匯出getfunclist介面,這樣的話可以實現對add sub介面的隱藏,當然這只是隱藏介面的一種方式,gcc還提供了一種方法,可以自定義匯出函式介面,只需在在編譯選項加上-wl,–version-script=funclist.txt即可,funclist.txt有一定的格式,內部定義了你要匯出的介面,如下
;
這樣便可以自由定義匯出介面了
好了,回歸正題
執行測試程式1
$ ./test1
test add [ 1+2 = 3]
test sub [ 1-2 = -1]
執行測試程式2
./test2
test add [ 1+2 = 3]
test sub [ 1-2 = -1]
test add [ 1+2 = 3]
test sub [ 1-2 = -1]
上述測試程式1展示了函式列表的使用方法,測試程式2展示了動態庫的動態載入及呼叫過程 linux 靜態庫 動態庫
1.概念和區別 靜態庫就是在編譯過程中一些目標檔案的集合。靜態庫在程式鏈結的時候使用,鏈結器會將程式中使用到函式的 從庫檔案中拷貝到應用程式中。一旦鏈結完成,在執行程式的時候就不需要靜態庫了。由於每個使用靜態庫的應用程式都需要拷貝所用函式的 所以靜態鏈結的檔案會比較大。相對於靜態函式庫,動態函式庫在...
linux 靜態庫 動態庫
linux支援兩種庫的型別 靜態庫和動態庫 共享庫 1.linux靜態庫和動態庫的命名規則 靜態函式庫 lib a 動態函式庫 lib so 這些庫檔案都是由 o檔案生成的 動態庫 程式執行過程中進行連線。可執行檔案 庫檔案 靜態庫 編譯時進行連線。庫檔案 的複製貼上過程。程式執行時先檢查依賴的庫檔...
Linux動態庫,靜態庫
1.庫是什麼?庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。就是將源 轉化為二進位制格式的源 相當於進行了加密,別人可以使用庫,但是看不到庫中的內容。2.靜態庫 靜態函式庫時在程式執行之前 編譯 就加入到目標程式中去了 linux中命名系統中靜態庫庫的規則 靜態庫檔名的命名方式是 l...