/lib
和/usr/lib
中,這是系統設定好的,因此會自動查詢這兩個目錄。通過使用一個或者多個-L選項,指定其他的查詢目錄。命令在執行的時候就會直接到我們指定的目錄下尋找連結檔案。gcc -L/home/lib mian.o -o main -ltest
執行命令結束,我們就可以得到最終的目標檔案。ldd option filename
option可以表示的選項如下:ldd -v main
顯示的資訊如下:
linux-vdso.so.1 (0x00007ffe6d730000)
libadd.so => /usr/lib/libadd.so (0x00007fca6e1c5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca6ddd4000)
/lib64/ld-linux-x86-64.so.2 (0x00007fca6e5c9000)
Version information:
./main:
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6:
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
void *dlopen (const char *filename, int flag);
dlopen用於開啟指定名字(filename)的動態連結庫(最好檔案絕對路徑),並返回操作控制代碼。
RTLD_NOW:立即決定,返回前解除所有未決定的符號。
RTLD_LAZY:暫緩決定,等有需要時再解出符號
gcc test.c -o test -ldl
2. 取函數執行地址的的函數為 dlsym,函數原型如下:void *dlsym(void *handle, char *symbol);
dlsym 根據動態連結庫操作控制代碼 (handle) 與符號 (symbol) ,返回符號對應的函數的執行程式碼地址。int dlclose (void *handle);
dlclose 用於關閉指定控制代碼的動態連結庫,只有當此動態連結庫的使用計數為 0 時,才會真正被系統解除安裝。返回值為 0 表示成功,非零表示失敗。const char *dlerror(void);
當動態連結庫操作函數執行失敗時,dlerror 可以返回出錯資訊,返回值為 NULL 時表示操作函數執行成功。/*sayhello.c*/ #include <stdio.h> void sayhello() { printf("hellon"); } /*saysomething.c*/ #include <stdio.h> void saysomething(char *str) { printf("%sn",str); }把上面這兩個函數製作成靜態庫檔案。使用命令:
gcc -shared -fpic sayhello.c saysomrthing.c -o libsayfn.so
呼叫函數如下:/*main.c*/ #include <stdio.h> #include <dlfcn.h> #include <stdlib.h> int main(int argc,char *argv[]) { void *handler; char *error; void (*sayhello)(void); void (*saysomething)(char *); handler = dlopen("libsayfn.so",RTLD_LAZY); if(error = dlerror()) { printf("%sn",error); exit(1); } sayhello = dlsym(handler,"sayhello"); if(error = dlerror()) { printf("%sn",error); exit(1); } saysomething = dlsym(handler,"saysomething"); if(error = dlerror()) { printf("%sn",error); exit(1); } sayhello(); saysomething("this is somethng"); dlclose(handler); return 0; }最後編譯main.c檔案,使用下面的命令:
gcc main.c -ldl -o main
編譯的時候需要注意,需要新增連結選項-ldl,還有就是在執行程式的時候需要把動態庫檔案放到指定的位置,否則就會出現動態庫找不到的錯誤資訊。
hello
This is something