嵌入式Linux文件IO,共享库(动态库)创建,添加加载路径和使用,LD_LIBRARY_PATH环
2019-07-12 14:46 发布
生成海报
文章目录
1,共享库的创建
a,编写库源码hello.c,bye.c
linux@linux:~/test/stdio/share_library$ vi hello.c
#include
void hello ( void )
{
printf ( "hello world
" ) ;
return ;
}
linux@linux:~/test/stdio/share_library$ vi bye.c
#include
void bye ( void )
{
printf ( "bye!
" ) ;
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
-fPIC选项:告诉编译器生成位置无关代码
位置无关代码:生成的".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
-shared选项:告诉编译器生成一个共享库
生成的共享库的文件名叫"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
#include "common.h"
int main ( int argc, const char * argv[ ] )
{
hello ( ) ;
bye ( ) ;
return 0 ;
}
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
“gcc test.c -o test.out -L. -lcommon”,可以发现此处共享库和静态库用法相同;GCC在链接时首先找共享库,如果共享库不存在,则链接静态库,如果静态库也找不到,则报错;加"-static"选项后,编译器会直接去找静态库。
执行时出错原因:因为程序链接的是共享库,并没有复制共享库中的代码,程序在执行时还会去加载用到的共享库,在加载的时候回去缺省的路径(比如"/lib","/usr/lib")下去寻找共享库,但是我们创建的库在当前目录下,并不在系统库的搜索路径里,所以在执行的时候找不到共享库就报错了;
创建好共享库后还需要添加共享库加载路径
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!
export:将原来的环境变量导出
“:“前面”$LD_LIBRARY_PATH"是引用原先的值;”:“后面的”.“是追加了当前目录;还可以追加其余共享库的路径,要用”:"隔开
此方法是临时的,只对当前终端有效。当重新打开一个终端再执行改程序时又会报错
b,把库拷贝到/usr/lib和/lib目录下
不建议采用这种方案,拷贝到该目录下需要管理员权限
一般系统库放在该目录下,程序员开发的库放在其他目录下更加合适
c,添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新
在/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:
文件中写入共享库路径
/ home/ linux/ test/ stdio/ share_library
使用ldconfig刷新
linux@linux:~/test/stdio/share_library$ sudo ldconfig
ldconfig会读取这个目录下面所有的配置文件,把配置文件路径中的库的所有信息提取出来
在多个终端都可执行测试程序
linux@linux:~/test/stdio/share_library$ ./test.out
hello world
bye!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮