嵌入式Linux文件IO,共享库(动态库)创建,添加加载路径和使用,LD_LIBRARY_PATH环境变量,/etc/ld.so.conf.d/目录下创建配置文件,ldconfig刷新配置文件

1,共享库的创建

a,编写库源码hello.c,bye.c

linux@linux:~/test/stdio/share_library$ vi hello.c 
#include <stdio.h>

void hello(void)
{
	printf("hello world\n");

	return ;
}
linux@linux:~/test/stdio/share_library$ vi bye.c 
#include <stdio.h>


void bye(void)
{
	printf("bye!\n");

	return ;
}

b,为共享库编写头文件common.h

#ifndef __COMMON_H__
#define __COMMON_H__

void hello(void);
void bye(void);

#endif

c,编译生成目标文件

linux@linux:~/test/stdio/share_library$ gcc -c hello.c bye.c -fPIC -Wall
linux@linux:~/test/stdio/share_library$ ls
bye.c  bye.o  common.h  hello.c  hello.o
  1. -fPIC选项:告诉编译器生成位置无关代码
  2. 位置无关代码:生成的".o文件"文件中的代码可以被加载到任意的地址执行。编译的时候用到了相对寻址而不是绝对寻址

d,创建共享库common

linux@linux:~/test/stdio/share_library$ gcc -shared hello.o bye.o -o libcommon.so.1
linux@linux:~/test/stdio/share_library$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so.1
  1. -shared选项:告诉编译器生成一个共享库
  2. 生成的共享库的文件名叫"libcommon.so.1",其中".so"表示这是一个共享库,".1"表示这个库的版本是1

e,为共享库文件创建链接文件

linux@linux:~/test/stdio/share_library$ ln -s libcommon.so.1 libcommon.so
linux@linux:~/test/stdio/share_library$ ll
total 36
drwxr-xr-x 2 linux linux 4096 11月  5 19:53 ./
drwxrwxr-x 5 linux linux 4096 11月  5 19:09 ../
-rw-rw-r-- 1 linux linux   70 11月  5 19:13 bye.c
-rw-rw-r-- 1 linux linux 1312 11月  5 19:38 bye.o
-rw-rw-r-- 1 linux linux   86 11月  5 19:24 common.h
-rw-r--r-- 1 linux linux   78 11月  5 19:29 hello.c
-rw-rw-r-- 1 linux linux 1324 11月  5 19:38 hello.o
lrwxrwxrwx 1 linux linux   14 11月  5 19:53 libcommon.so -> libcommon.so.1*
-rwxrwxr-x 1 linux linux 6937 11月  5 19:51 libcommon.so.1*

2,共享库的使用

a,编写测试程序test.c

#include <stdio.h>
#include "common.h"

int main(int argc, const char *argv[])
{
	hello();
	bye();

	return 0;
}

b,编译test.c并链接共享库libcommon.so

linux@linux:~/test/stdio/share_library$ gcc test.c -o test.out -L. -lcommon
linux@linux:~/test/stdio/share_library$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so  libcommon.so.1  test.c  test.out
linux@linux:~/test/stdio/share_library$ ./test.out 
./test.out: error while loading shared libraries: libcommon.so: cannot open shared object file: No such file or directory
  1. “gcc test.c -o test.out -L. -lcommon”,可以发现此处共享库和静态库用法相同;GCC在链接时首先找共享库,如果共享库不存在,则链接静态库,如果静态库也找不到,则报错;加"-static"选项后,编译器会直接去找静态库。
  2. 执行时出错原因:因为程序链接的是共享库,并没有复制共享库中的代码,程序在执行时还会去加载用到的共享库,在加载的时候回去缺省的路径(比如"/lib","/usr/lib")下去寻找共享库,但是我们创建的库在当前目录下,并不在系统库的搜索路径里,所以在执行的时候找不到共享库就报错了;
  3. 创建好共享库后还需要添加共享库加载路径

3,添加共享库的加载路径

a,在LD_LIBRARY_PATH环境变量中库所在路径

linux@linux:~/test/stdio/share_library$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
linux@linux:~/test/stdio/share_library$ ./test.out 
hello world
bye!
  1. export:将原来的环境变量导出
  2. “:“前面”$LD_LIBRARY_PATH"是引用原先的值;”:“后面的”.“是追加了当前目录;还可以追加其余共享库的路径,要用”:"隔开
  3. 此方法是临时的,只对当前终端有效。当重新打开一个终端再执行改程序时又会报错

b,把库拷贝到/usr/lib和/lib目录下

  1. 不建议采用这种方案,拷贝到该目录下需要管理员权限
  2. 一般系统库放在该目录下,程序员开发的库放在其他目录下更加合适

c,添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新

  1. 在/etc/ld.so.conf.d/目录下创建my_common.conf文件
linux@linux:~/test/stdio/share_library$ sudo vi /etc/ld.so.conf.d/my_common.conf
[sudo] password for linux: 
  1. 文件中写入共享库路径
/home/linux/test/stdio/share_library
  1. 使用ldconfig刷新
linux@linux:~/test/stdio/share_library$ sudo ldconfig

ldconfig会读取这个目录下面所有的配置文件,把配置文件路径中的库的所有信息提取出来

  1. 在多个终端都可执行测试程序
linux@linux:~/test/stdio/share_library$ ./test.out 
hello world
bye!

猜你喜欢

转载自blog.csdn.net/m0_37542524/article/details/83756626
今日推荐