linux動態庫(二)

2021-07-04 19:59:43 字數 3711 閱讀 4640

上篇文章呈現了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...