Dynamically loaded libraries 動態載入庫
動態載入函式庫可以由程式控制在需要時才載入、釋放,在編譯連結時不需要相關的界面與函式庫,可以用來設計軟體插件之類的功能。
範例函式庫
mylib.h
void hello();
void world();
hello.c
#include "mylib.h"
#include <stdio.h>
void hello(){
printf("Hello");
}
world.c
#include "mylib.h"
#include <stdio.h>
void world(){
printf("World");
}
編譯
$ gcc -c -fPIC hello.c world.c
$ gcc -shared -o libmylib.so hello.o world.o
-fPIC
要編譯器產生 position-independent code-shared
編譯 Shared Library-o libmylib.so
函式庫檔案名稱為 libmylib.so
這裡沒使用
soname
等便於版本維護的參數
這樣會建立一個 libmylib.so 共享函式庫
使用方式
main.c
#include <dlfcn.h> /* 動態載入要用的相關函式標頭 */
#include <stdio.h>
int main() {
/* 載入函式庫 libmylib.so */
void* handle = dlopen("./libmylib.so", RTLD_LAZY);
/* 若有錯誤可以取得錯誤訊息 */
char* err = dlerror();
if (err) {
printf(err);
return 0;
}
/* 取得void hello()函式的指標 */
void (*f1)() = (void (*)()) dlsym(handle, "hello");
/* 若有錯誤可以取得錯誤訊息 */
err = dlerror();
if (err) {
printf(err);
return 0;
}
/* 取得void world()函式的指標 */
void (*f2)() = (void (*)()) dlsym(handle, "world");
/* 若有錯誤可以取得錯誤訊息 */
err = dlerror();
if (err) {
printf(err);
return 0;
}
/* 兩個函式指標都有取得就呼叫 */
if (f1 && f2) {
f1();
f2();
printf("\n");
}
/* 釋放動態函式庫 */
dlclose(handle);
return 0;
}
編譯
編譯時要連結libdl,使用-ldl
$ gcc main.c -ldl
執行
$ ./a.out
結果
HelloWorld
c++ 並不直接適用此範例
以上是c在linux上使用動態載入庫的範例,
若要設計c++的動態載入庫需要用
否則沒辦法順利的取得函式指標,
或是使用
有關於c++動態載入庫的範例在下一篇。
若要設計c++的動態載入庫需要用
extern "C"
讓c++編譯器不修飾函式名稱(Name Mangling),否則沒辦法順利的取得函式指標,
或是使用
readelf -s libmylib.so
來尋找修飾後的函式名稱,有關於c++動態載入庫的範例在下一篇。
留言
張貼留言