參考大佬:
http://blog.sina.com.cn/s/blog_a4f2bd7d010114ka.html
test.h
#ifndef _TEST_H
#define _TEST_H
void test_a();
void test_b();
#endif
test_a.c
#include
#include "test.h"
void test_a()
{
printf("test in test_a..../n");
}
test_b.c
#include
#include "test.h"
void test_b()
{
printf("test in test_b..../n");
}
test.c
#include
#include "test.h"
int main()
{
test_a();
test_b();
return 0;
}
main.c
#include
#include
int main()
{
void *handle;
char *error;
void (*test_a)();
void (*test_b)();
if((handle = dlopen("./libtest.so",RTLD_LAZY)) == NULL)
{
printf("dlopen error/n");
return -1;
}
test_a = dlsym(handle,"test_a");
test_b = dlsym(handle,"test_b");
if((error = dlerror()) != NULL)
{
printf("dlsym error /n");
return -1;
}
test_a();
test_b();
dlclose(handle);
return 0;
}
編譯成動態庫libtest.so
gcc test_a.c test_b.c -fPIC -shared -o libtest.so
gcc -o test test.c ./libtest.so
ldd test
gcc -o main main.c -ldl
Linux中DSO函數操作
void* dlopen(const char *pathname, int mode);
該函數函數來加載動態庫,其中pathname是需要加載的庫的路徑名稱,mode則是加載的方式,可以是三個值:RTLD_LAZY用來表示認為未定義的符號是來自動態鏈接庫的代碼;RTLD_NOW則表示要在dlopen返回前確定所有未定義的符號,如果不能完成則失敗;而RTLD_GLOBAL則意味着動態鏈接庫中定義的外部符號將可以由隨后加載的庫所使用。如果函數執行成功,其將返回動態鏈接庫的一個句柄。
一旦對動態庫進行了加載,我們則可以通過dlsym函數獲取庫中的函數調用以及各種定義的符號等等。其函數原型如下:
void* dlsym(void* handle, char* symbol);
其中,handle是加載的動態鏈接庫的句柄,其通常是dlopen函數的操作結果;symbol則是需要得到的動態鏈接庫中的符號名稱。如果找不到symbol,函數將返回NULL。
在所有的操作結束后,Linux可以通過dlclose將dlopen先前打開的共享對象從當前進程斷開,不過只有動態鏈接庫的使用記數為0的時候該共享對象才會真真被卸載。dlclose的函數原型如下:
int dlclose(void* handle);
一旦使用dlclose關閉了對象,dlsym就再也不能使用它的符號了。
