我都說這些是放再經書 (C tools) 最末頁妖魔鬼怪API ....
原理網路上很多,這裡簡單筆記就好。
dlopen和dlsym是用於打開動態鏈接庫中的函數,將動態鏈接庫中的函數或類導入到本程序中:
dlopen函數:
功能:打開一個動態鏈接庫
dlsym函數:
函數原型是
void* dlsym(void* handle,const char* symbol)
該函數在<dlfcn.h>文件中。
handle是由dlopen打開動態鏈接庫後返回的指針,symbol就是要求獲取的函數的名稱,函數 返回值是void*,指向函數的地址,供調用使用。
先寫一個so 來讀:
root@bejo:/home/bejo/code/test# cat libso.c
#include <stdio.h>
int bejo_lib(char *name, int i)
{
printf("I am %s, do i=%d\n", name, i);
return 0;
}
#include <stdio.h>
int bejo_lib(char *name, int i)
{
printf("I am %s, do i=%d\n", name, i);
return 0;
}
包成 dynamic using
#gcc -c libso.c
#gcc -shared -o libso.so libso.o
寫一個使用者~*
root@bejo:/home/bejo/code/test# cat use.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int *argc, char **argv)
{
void *fHandle;
void (*func)();
fHandle = dlopen("./libso.so",RTLD_LAZY);
if (!fHandle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
func = (void(*)())dlsym(fHandle,"bejo_lib");
if (func) {
func("BEJO", 999);
}
dlclose(fHandle);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int *argc, char **argv)
{
void *fHandle;
void (*func)();
fHandle = dlopen("./libso.so",RTLD_LAZY);
if (!fHandle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
func = (void(*)())dlsym(fHandle,"bejo_lib");
if (func) {
func("BEJO", 999);
}
dlclose(fHandle);
return 0;
}
包一包,記得加上 -ldl ---> libdl.so
#gcc use.c -ldl -o use#include <stdio.h>
#include <stdlib.h>#include <dlfcn.h>
int main(int *argc, char **argv)
{
void *fHandle;
double (*func)();
fHandle = dlopen("./libm.so.6",RTLD_LAZY);
if (!fHandle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
func = (double(*)())dlsym(fHandle,"fabs");
if (func) {
printf("fabs = %f\n", func(-12.345));
}
dlclose(fHandle);
return 0;
}
# ./use
I am BEJO, do i=999
I am BEJO, do i=999
--
上面其實都在工具書可以查到
這本真的是聖經阿....
來作點無聊的事...
如果你手上拿到一個陌生的so 檔又想跑跑看?
ex:
#cp cp /lib/i386-linux-gnu/libm.so.6
這個好了。lib math
那就:
#readelf -s libm.so.6 | grep fabs
0000bdb0 7 FUNC WEAK DEFAULT 13 fabs@@GLIBC_2.0
有耶,這是一個把浮點數取決對值的方法
修改一下use.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int *argc, char **argv)
{
void *fHandle;
double (*func)();
fHandle = dlopen("./libm.so.6",RTLD_LAZY);
if (!fHandle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
func = (double(*)())dlsym(fHandle,"fabs");
if (func) {
printf("fabs = %f\n", func(-12.345));
}
dlclose(fHandle);
return 0;
}
#include <stdlib.h>
#include <dlfcn.h>
int main(int *argc, char **argv)
{
void *fHandle;
double (*func)();
fHandle = dlopen("./libm.so.6",RTLD_LAZY);
if (!fHandle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
func = (double(*)())dlsym(fHandle,"fabs");
if (func) {
printf("fabs = %f\n", func(-12.345));
}
dlclose(fHandle);
return 0;
}
輸出:
# ./use
fabs = 12.345000
fabs = 12.345000
恩... 好吧。我真無聊 囧>
其實這幾個function 就在工具書裡面,尤其是最末頁幾個妖魔鬼怪專用API,平常工作開發不大會用到,有看到也就review open source 的時候
這次跟其他部門合作剛好有開發到,負責撰寫*.so 檔,來切開開發工作。
平行的開發方法很多種技巧,像常見的靠include 來切割C files、module 。
而這種不需要header 的方式,讓開發平行很多。
也非常適合來作 user space 的insert packaget module
妖魔鬼怪還有一組 share memory API 剛好這次噴bug 在這裡,下次再來筆記一下。
沒有留言:
張貼留言