Linux装载和启动一个可执行程序
来源:互联网 发布:金庸和古龙 知乎 编辑:程序博客网 时间:2024/06/05 20:04
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
几个概念
库文件
程序员可以把自己的代码打包成库文件,再提供一个头文件即可。库文件包括 静态库和共享库(动态库)。
静态库的使用方式是代码的复制,共享库的使用方式是函数指针(函数地址)
静态库(.a)
优点:代码独立,效率稍好缺点:代码的空间太大,不利于修改和维护
共享库(.so)
优先:代码空间较小,修改,维护比较方便缺点:代码依赖于共享库文件
实际开发中共享库的使用更加广泛
静态库的使用步骤
1 、生成静态库文件(.a)
>写源代码>编译生成目标文件(.o)
>使用 ar -r 命令生成静态库文件
ar -r lib___.a ____.o
2 、调用静态库文件
(前提:需要 lib__.a 和__.h 文件)>写调用源代码
>编译(gcc -c)
>链接静态库文件,有三种方式
>编译(gcc -c)
>链接静态库文件,有三种方式
1.gcc __.o lib__.a(直接连接不推荐)
2.配置环境变量 LIBRARY_PATH,把库文件所在路径配进去然后用 gcc __.c -l__(库文件 lib后面名字)
3.gcc __.o -l__ -L 库文件路径
$cd slib$lsadd.c add.h test.c//编译生成.o 文件$gcc -c add.c$lsadd.c add.h add.o test.c//利用.o 文件生成静态库.a 文件$ar -r libmylib.a add.oar: creating libmylib.a//第一种链接方式/运行$gcc test.c libmylib.a$a.outr1=5,r2=5.000000//第二种链接方式/运行$export LIBRARY_PATH=.$gcc test.c -lmylib$a.outr1=5,r2=5.000000//第三种链接方式/运行$gcc test.c -lmylib -L.$a.outr1=5,r2=5.000000
共享库的使用步骤
1 、生成 共享库文件.so
>写源代码>编译生成目标文件.o
gcc -c -fpic __.c #-fpic 可以不加>生成共享库文件
gcc -shared __.o -o lib__.so
2 、调用 共享库文件和静态库一样
注意:要运行共享库程序必须配置 LD_LIBRARY_PATH
LD_LIBRARY_PATH:
编译没有影响主要影响运行
$lsDprint.c Jprint.c print.h test.c$gcc -c Dprint.c$gcc -shared Dprint.o -o libdt.so$export LD_LIBRARY_PATH=.$gcc test.c -ldt -L.
动态编程
(使用程序直接调用库文件的函数)<dlfcn.h>加载动态库的头文件
步骤:
1.用 dlopen 打开一个库文件,返回 void*即动态库首地址
2.用 dlsym 按函数名打开一个函数,返回函数指针
3.使用函数指针
4.用 dlclose 关闭库文件
5.dlerror 函数判断是否出错,!=NULL 出错
步骤:
1.用 dlopen 打开一个库文件,返回 void*即动态库首地址
2.用 dlsym 按函数名打开一个函数,返回函数指针
3.使用函数指针
4.用 dlclose 关闭库文件
5.dlerror 函数判断是否出错,!=NULL 出错
打开库文件
void *dlopen(const char *filename, int flag);RTLD_LAZY:runtime library dynamic lazy 延迟加载
RTLD_NOW: runtime library dynamic now 直接加载
获取出错信息
char *dlerror(void);<span style="color: rgb(102, 102, 102); font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px;">返回NULL 代表没有错</span>返回NULL 代表没有错
获取库函数指针
关闭动态库
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
void* handle 是 dlopen 的返回值
const char *symbol 是函数名
返回值是函数指针
#include <stdio.h>#include <dlfcn.h>int main(){<span style="white-space:pre"></span>void * handle = dlopen("./libadd.so", RTLD_NOW); <span style="white-space:pre"></span>char* error = dlerror(); <span style="white-space:pre"></span>if (error) <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>printf("open error"); <span style="white-space:pre"></span>return -1; <span style="white-space:pre"></span>}<span style="white-space:pre"></span>//int print(int,int);函数原型<span style="white-space:pre"></span>int (*f)(int, int); //函数指针,函数名用*f替换函数名<span style="white-space:pre"></span>f = dlsym(handle, "add");<span style="white-space:pre"></span>if (error)<span style="white-space:pre"></span>{ <span style="white-space:pre"></span>printf("sym error\n"); <span style="white-space:pre"></span>return -1; <span style="white-space:pre"></span>} <span style="white-space:pre"></span>int r = f(1, 2); <span style="white-space:pre"></span>printf("r=%d\n", r); <span style="white-space:pre"></span>dlclose(handle); <span style="white-space:pre"></span>return 0;}
0 0
- Linux装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序(Linux)
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- 初学《Linux内核如何装载和启动一个可执行程序》
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- 6.Linux内核如何装载和启动一个可执行程序
- 7.Linux内核如何装载和启动一个可执行程序
- ORACLE各种插入数据方式对比
- 欢迎使用CSDN-markdown编辑器
- UVA_10099_The Tourist Guide_kruscal
- 使用Python操作Redis
- 【MFC】:MFC中实现文件追加的方法
- Linux装载和启动一个可执行程序
- 如何自己动手实现 KVO
- C#实例之计算字符串中不同字符的个数
- C++虚函数分析[2]--虚函数介绍
- PHP的session存放路径及其配置session.save_path
- Bloom Filter算法和实现
- Python 程序设计语言 笔记(六)
- 水池数目
- Java并发编程系列之二十:Fork/Join框架