您的位置:首页 > 运维架构 > Linux

Linux程序运行中加载动态库

2015-03-16 18:09 141 查看

Linux程序运行中加载动态库

Linux C/C++程序通常是在编译的时候链接依赖的动态库.

同时,也提供一种在运行时加载动态库的方法.(具体man dlopen中有说明和使用范例.)

应用的场景,暂时想到是 :

类似插件.不用更新整个应用程序,通过更新或新增动态库,实现更新或者增加功能.

在之前的一个开源的项目streamtunner中就有使用这种. 用户可以更新或自行新增网络源.

方便更新和调试

由不同开发人员实现统一接口,按照动态库的形式输出. 调用者可以在不修改源码同时不用重新编译主程序的情况下,调用接口实现.

针对第二种场景, 下面是一个示例.(main中是拷贝自man dlopen中的范例.)

Makefile

all:
@#动态库编译.
gcc -Wall -c -o sort_a.o sort_a.c
gcc -shared -fPIC -o libsorta.so sort_a.o
@#可执行程序编译.
gcc -Wall -o sortcall main.c -ldl


sort_a.c

int sort_a(int* a, int n)
{
int ret = 0;

int i;
int j;
int tmp;

for(i=0; i<n; i++) {
for(j=i+1; j<n; j++) {
if(a[i] > a[j]) {
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}

return ret;
}


main.c

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char **argv)
{
void *handle;
int (*sort)(int*, int);
char *error;

if(2 != argc) {
fprintf(stderr, "%s\n", "usage : sortcall filepath.");
exit(EXIT_FAILURE);
}

handle = dlopen(argv[1], RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}

dlerror();    /* Clear any existing error */

/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
The assignment used below is the POSIX.1-2003 (Technical
Corrigendum 1) workaround; see the Rationale for the
POSIX specification of dlsym(). */

*(void **) (&sort) = dlsym(handle, "sort_a");

if ((error = dlerror()) != NULL)  {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}

int a[6] = {1, 4, 6, 3, 2, 1};

(*sort)(a, 6);

int i;
for(i=0; i<6; i++) {
printf("%d ", a[i]);
}
printf("\n");

dlclose(handle);
exit(EXIT_SUCCESS);
}


执行 : ./sortcall libsorta.so

其他开发人员可以实现不同的排序方法后, 以动态库xxx.so的形式输出.

即可调用 ./sortcall xxx.so以测试不同的排序实现.

以上,谢谢.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: