博客
关于我
linux动态库编译和使用详细剖析
阅读量:435 次
发布时间:2019-03-06

本文共 3119 字,大约阅读时间需要 10 分钟。

Linux上使用GCC编译动态库的实践指南

引言

在Linux系统开发中,动态库的使用是不可或缺的一部分。通过本文,你将深入了解如何在Linux上使用GCC编译动态库,并通过实际案例分析动态库的构建与使用。同时,本文将简要介绍动态库插件技术,帮助你实现代码的向后兼容。

本文将从静态库的基础构建入手,逐步展开到动态库的创建与使用。通过实际案例分析,你将掌握动态库的编译与链接流程,并了解如何在程序中加载和使用动态库。


静态库的构建与使用

在Linux系统中,静态库的创建相对简单。静态库的主要作用是将程序的依赖性编译到可执行文件中,避免了运行时的依赖冲突。

静态库的创建命令:

ar rcs libheoo.a heoo-getvalue.o heoo-getkey.o

静态库的使用命令:

gcc -g -Wall -o main.out main.c -L. -lheoo

在上述命令中,-L. 表示查找当前目录下的动态库,-lheoo 表示链接静态库 libheoo.a


动态库的构建与使用

动态库的优势在于它能够在程序运行时加载,减少了程序的启动时间,并支持代码的向后兼容。以下是动态库的基本构建命令:

动态库的创建命令:

gcc -shared -fPIC -o libheoo.so heoo.c

动态库的使用命令:

gcc -g -Wall -o main.out main.c -L. -lheoo

如果动态库位于当前目录下,可以通过设置LD_LIBRARY_PATH环境变量来指定查找路径:

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:./"gcc -g -Wall -o main.out main.c -L. -lheoo

动态库的显式加载

在某些场景下,程序可能需要显式加载动态库。以下是一个示例代码,展示了如何通过dlopendlsym函数加载动态库:

#include 
#include
#define _STR_PATH "./libheoo.so"int main(int argc, char* argv[]) { const char* (*getkey)(void); const void* (*getvalue)(void* arg); void* handle = dlopen(_STR_PATH, RTLD_LAZY); const char* err = dlerror(); if (!handle || err) { fprintf(stderr, "dlopen %s 失败!\n", _STR_PATH); return -1; } getkey = dlsym(handle, "getkey"); err = dlerror(); if (err) { fprintf(stderr, "获取getkey函数失败!\n"); dlclose(handle); return -2; } puts(getkey()); getvalue = dlsym(handle, "getvalue"); err = dlerror(); if (err) { fprintf(stderr, "获取getvalue函数失败!\n"); dlclose(handle); return -3; } puts((char*)getvalue(NULL)); dlclose(handle); return 0;}

编译命令:

gcc -g -Wall -o heooso.out heooso.c -ldl

动态库插件技术

为了实现代码的向后兼容,可以通过动态库插件技术将新功能动态加载到已有的程序中。以下是一个简单的插件开发示例:

插件接口定义:

#ifndef _H_HEOO#define _H_HEOOtypedef struct {    void* handle;    const char* (*getkey)(void);    const void* (*getvalue)(void* arg);} HeooPlugin;HeooPlugin* heoo_createPlugin(void);void heoo_loadPlugin(HeooPlugin* plugin, const char* pluginPath);void heoo_unloadPlugin(HeooPlugin* plugin);#endif /* _H_HEOO */

插件实现:

#include 
#include
#define _STR_PATH "./libheoo.so"int main(int argc, char* argv[]) { HeooPlugin* plugin; plugin = heoo_createPlugin(); if (!plugin) { fprintf(stderr, "创建插件失败!\n"); return -1; } heo_new(plugin, 3, "./"); if (heo_new失败) { fprintf(stderr, "初始化插件失败!\n"); heo_del(plugin, 3); return -2; } puts("插件已加载!\n"); return 0;}

插件编译命令:

gcc -fPIC -shared -o libheoo.so heoo.c

Makefile自动化构建

为了简化开发流程,可以通过Makefile实现自动化构建。以下是一个简单的Makefile示例:

CC = gccDEBUG = -g -WallLIB = -ldlRUNSO = $(CC) -fPIC -shared -o $@all: libheoo.so libheootwo.so libheoothree.so main.outlibheoo.so: heoo.c    $(RUNSO) libheoo.so heoo.clibheootwo.so: heootwo.c    $(RUNSO) libheootwo.so heootwo.clibheoothree.so: heoothree.c    $(RUNSO) libheoothree.so heoothree.cmain.out: main.c    $(CC) $(DEBUG) -o main.out main.c $(LIB)clean:    rm -rf *.so *.s *.i *.o *.out *~

总结

通过本文的实践指南,你已经掌握了Linux上使用GCC编译动态库的基础知识,并了解了静态库与动态库的区别。动态库的使用为程序的扩展和维护提供了极大的灵活性,同时通过插件技术,你可以轻松实现代码的向后兼容。希望本文的内容能为你的Linux开发之路提供有价值的参考!

转载地址:http://rniyz.baihongyu.com/

你可能感兴趣的文章
PHPExcel导入导出 若在thinkPHP3.2中使用(无论实例还是静态调用(如new classname或classname::function)都必须加反斜杠,因3.2就命名空间,如/c...
查看>>
PHPMailer发送邮件
查看>>
phpmailer发送邮件,可以带附件
查看>>
phpmyadmin 安装
查看>>
phpmyadmin数据库建表及插入
查看>>
phprpc简单使用
查看>>
phpstorm中Xdebug的使用
查看>>
phpstorm配置php脚本执行
查看>>
phpStudy安装教程
查看>>
phpunit
查看>>
phpWhois 项目推荐
查看>>
phpwind部署问题
查看>>
PHP__call __callStatic
查看>>
php一句话图片运行,【后端开发】php一句话图片木马怎么解析
查看>>
php上传文件找不到临时文件夹
查看>>
PHP下curl用法分析
查看>>
redis事务操作
查看>>
PHP中array_merge和array相加的区别分析
查看>>
PHP中dirname(__FILE__)的意思
查看>>
PHP中extract()函数的妙用
查看>>