linux动态连接库

本文通过实例代码展示了在Linux环境下,使用dlopen动态加载同一个共享库(.so文件)的过程。当两个应用进程(APP1和APP2)各自调用dlopen加载同一库时,返回的句柄值相同。共享库中的全局变量g_count在两个进程中独立计数,表明每个进程拥有独立的内存空间。通过观察so.txt和test.txt的内容,可以看出每个应用对共享库的调用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在同一个进程中多次dlopen同一个so库,返回的句柄值是一样的


共享库例子代码(hell.c):

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int g_count = 0;
int add_count()
{
g_count +=1;
char buff[64] = {0};
int fd;
fd = open("so.txt", O_RDWR | O_APPEND);
// printf("g_count= %d\r\n", g_count);
sprintf(buff, "g_count= %d\r\n", g_count);
write(fd, buff, 64);
sync();
sleep(1);
return g_count;
}


APP1例子代码(app1.c)

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


int main(int argc, char *argv[])
{
void *handle;
int (*fun_han)();
int cnt = 0;


int fd;
char buf[64] = {0};
fd = open("test.txt", O_RDWR | O_APPEND);
// printf("[%d]\r\n", __LINE__);


// printf("hello world\n");
#if 1
handle = dlopen("/home/yang/exam/hell.so", RTLD_LAZY | RTLD_GLOBAL);
if(NULL == handle){
printf("[%d]%s\n",__LINE__, dlerror());
}


// printf("[%d]\r\n", __LINE__);
fun_han = (int (*)())dlsym(handle,"add_count");
if(NULL == handle){
printf("[%d]%s\n",__LINE__, dlerror());
}


for(;;){
cnt = fun_han();
// printf("[%d]app1 cnt = %d\r\n",__LINE__, cnt);
sprintf(buf, "app1 cnt = %d\r\n", cnt);
write(fd, buf, 64); 
sync();
}

dlclose(handle);
#endif
return 0;
}

APP2例子代码

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


int main(int argc, char *argv[])
{
void *handle;
int (*fun_han)();
int cnt = 0;


int fd;
char buf[64] = {0};
fd = open("test.txt", O_RDWR | O_APPEND);
// printf("[%d]\r\n", __LINE__);


// printf("hello world\n");
#if 1
handle = dlopen("/home/yang/exam/hell.so", RTLD_LAZY | RTLD_GLOBAL);
if(NULL == handle){
printf("[%d]%s\n",__LINE__, dlerror());
}


// printf("[%d]\r\n", __LINE__);
fun_han = (int (*)())dlsym(handle,"add_count");
if(NULL == handle){
printf("[%d]%s\n",__LINE__, dlerror());
}


for(;;){
cnt = fun_han();
// printf("[%d]app1 cnt = %d\r\n",__LINE__, cnt);
sprintf(buf, "app2 cnt = %d\r\n", cnt);
write(fd, buf, 64); 
sync();
}

dlclose(handle);
#endif
return 0;
}

编译:编译共享库:

gcc -o libhell.so -fPIC -shared -g hell.c

编译应用程序

gcc -o app1 -ldl libhell.so app1.cgcc -o app2 -ldl libhell.so app2.c

添加动态库路径

export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH

或在/etc/ld.so.conf文件中添加动态库所在的目录

执行程序:

./app1 &.

/app2 &

查看结果:

so.txt内容:

g_count= 1
g_count= 2
g_count= 3
g_count= 4
g_count= 5
g_count= 6
g_count= 1
g_count= 7
g_count= 2
g_count= 8
g_count= 3
g_count= 9
g_count= 4
g_count= 10
g_count= 11
g_count= 12
g_count= 13
g_count= 14

test.txt内容:

app1 cnt = 1
app1 cnt = 2
app1 cnt = 3
app1 cnt = 4
app1 cnt = 5
app1 cnt = 6
app2 cnt = 1
app1 cnt = 7
app2 cnt = 2
app1 cnt = 8
app2 cnt = 3
app1 cnt = 9
app1 cnt = 10
app1 cnt = 11
app1 cnt = 12
app1 cnt = 13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值