[动态库]动态库生成和使用以及Makefile编写
转自:https://www.cnblogs.com/ljtknowns/p/5647793.html
文件目录结构如下
1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5 dynamiclib/Makefile 6 dynamiclib/dynamiclib_add.c 7 dynamiclib/dynamiclib_mul.c 8 dynamiclib/inc/dynamiclibs.h 9 dynamiclib/libs/
1. dynamiclib目录
dynamiclib/inc/dynamiclibs.h 文件内容如下:
1 #ifndef __dynamic_libs_h__ 2 #define __dynamic_libs_h__ 3 4 #include "apue.h" 5 int dynamic_lib_func_add(int i1, int i2); 6 int dynamic_lib_func_mul(int i1, int i2); 7 8 #endif
dynamiclib/dynamiclib_add.c 文件内容如下:
1 #include "dynamiclibs.h" 2 3 int dynamic_lib_func_add(int i1, int i2) 4 { 5 int iret = i1 + i2; 6 printf("... in .so func, %d add %d,return %d\n", i1, i2, iret); 7 return iret; 8 }
dynamiclib/dynamiclib_mul.c 文件内容如下:
1 #include "dynamiclibs.h" 2 3 int dynamic_lib_func_mul(int i1, int i2) 4 { 5 int iret = i1 * i2; 6 printf("... in .so func, %d multiplys %d, retun %d\n", i1, i2, iret); 7 return iret; 8 }
dynamiclib/Makefile 文件内容如下:
1 CC = gcc 2 CFLAGS = -Wall -g -O -fPIC 需要加上 -fPIC3 CXXFLAGS = 4 INCLUDE = -I ./inc -I ../comm/inc5 TARGET = libmytest.so6 LIBPATH = ./libs/7 8 vpath %.h ./inc9 10 OBJS = dynamiclib_add.o dynamiclib_mul.o 11 SRCS = dynamiclib_add.c dynamiclib_mul.c 12 13 $(OBJS):$(SRCS) 14 $(CC) $(CFLAGS) $(INCLUDE) -c $^ 15 16 all:$(OBJS) 17 $(CC) -shared -fPIC -o $(TARGET) $(OBJS) 需要加上 -shared -fPIC 18 mv $(TARGET) $(LIBPATH) 19 20 clean: 21 rm -f *.o 22 rm -f $(LIBPATH)*
以上文件,就可以生成动态库文件 libmytest.so,应用程序以两种方式加载动态库函数,如下
2. 在编译应用程序时加载动态库
dynamiclibapp.c 文件内容如下:
1 #include "apue.h"2 #include "dynamiclibs.h"3 4 int main(int argc, char *argv[])5 {6 err_msg("step in main\n");7 dynamic_lib_func_add(1, 9); 8 dynamic_lib_func_mul(1, 9); 9 err_msg("step out main\n"); 10 11 return 0; 12 }
Makefile 文件内容如下:
1 CC = gcc 2 CFLAGS = -Wall -O -g3 CXXFLAGS = 4 INCLUDE = -I ./comm/inc -I ./dynamiclib/inc5 TARGET = dynamiclibapp6 LIBVAR = -lmytest 指明需要链接动态库 libmytest.so7 LIBPATH = -L./dynamiclib/libs 指明 libmytest.so 的路径8 #search paths for errorhandler.c9 vpath %.c ./comm 10 #下行是为依赖项 apue.h 准备的,比如 [errorhandler.o:errorhandler.c apue.h] 里的 apue.h 11 vpath %.h ./comm/inc 12 13 OBJS = errorhandler.o dynamiclibapp.o 14 #下行的 apue.h,可以不必写出来 15 errorhandler.o:errorhandler.c apue.h 16 $(CC) $(CFLAGS) $(INCLUDE) -c $^ 17 dynamiclibapp.o:dynamiclibapp.c apue.h 18 $(CC) $(CFLAGS) $(INCLUDE) -c $^ 19 20 all:$(OBJS) $(LIB) 21 cd ./dynamiclib && make all 22 $(CC) $(CFLAGS) $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR) 23 在上行中,在执行编译时,加载了 libmytest.so 中函数 24 clean: 25 rm -f *.o 26 rm -f comm/inc/*.gch 27 rm -f $(TARGET) 28 cd ./dynamiclib && make clean
对于这种方式编译出来的动态库文件,还需要在 /etc/ld.so.conf.d/ 目录中添加 libmytest.so 库文件的路径说明,
即在 /etc/ld.so.conf.d/ 目录中新建配置文件 mytest.conf,且执行 ldconfig, /etc/ld.so.conf.d/mytest.conf 的文
件内容为 libmytest.so 库文件的绝对路径,例如:
1 /home/lijiangtao/dynamiclib/libs
如果不在编译应用程序时加载动态库文件里的函数,而是改为在应用程序执行时(比如:程序的main函数启动期
间,或在程序执行期间)加载 libmytest.so 里函数,那么就可以不需在 /etc/ld.so.conf.d/ 目录中配置 libmytest.so
路径,具体如下所述。
3. 在应用程序执行时加载动态库
dynamiclibapp.c 文件内容如下:
1 #include "apue.h"2 #include "dynamiclibs.h"3 #include <dlfcn.h>4 5 typedef int (*fp_lib_add)(int, int);6 typedef int (*fp_lib_mul)(int, int);7 typedef void* dlhandle;8 9 dlhandle dll = NULL; 10 fp_lib_add func_add = NULL; 11 fp_lib_mul func_mul = NULL; 12 13 dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul); 14 15 int main(int argc, char *argv[]) 16 { 17 char *pso = "/home/lijiangtao/dynamiclib/libs/libmytest.so";//指定 .so 路径 18 dll = load_dynamic_func(pso, &func_add, &func_mul);//程序执行时,加载动态函数 19 err_msg("step in main\n"); 20 func_add(1, 9);//执行 add 函数 21 func_mul(1, 9);//执行 mul 函数 22 err_msg("step out main\n"); 23 24 return 0; 25 } 26 27 dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul) 28 { 29 if(NULL == psopath ||'\0' == psopath[0]) 30 return NULL; 31 char *perrormsg = NULL; 32 dlhandle dllhandle = dlopen(psopath, RTLD_LAZY); 33 if(NULL == dllhandle) 34 { 35 printf("%s\n", dlerror()); 36 return NULL; 37 } 38 if(NULL != padd) 39 { 40 *padd = dlsym(dllhandle, "dynamic_lib_func_add");//加载 add 函数 41 perrormsg = dlerror(); 42 if(NULL != perrormsg) 43 printf("%s\n", perrormsg); 44 } 45 if(NULL != pmul) 46 { 47 *pmul = dlsym(dllhandle, "dynamic_lib_func_mul");//加载 mul 函数 48 perrormsg = dlerror(); 49 if(NULL != perrormsg) 50 printf("%s\n", perrormsg); 51 } 52 return dllhandle; 53 }
Makefile 文件内容如下:
1 CC = gcc 2 CFLAGS = -Wall -O -g3 CXXFLAGS = 4 INCLUDE = -I ./comm/inc -I ./dynamiclib/inc5 TARGET = dynamiclibapp6 LIBVAR = -ldl 需要链接 libdl.so 库7 LIBPATH = 8 #search paths for errorhandler.c9 vpath %.c ./comm 10 #下行是为依赖项 apue.h 准备的,比如 [errorhandler.o:errorhandler.c apue.h] 里的 apue.h 11 vpath %.h ./comm/inc 12 13 OBJS = errorhandler.o dynamiclibapp.o 14 #下行的 apue.h,可以不必写出来 15 errorhandler.o:errorhandler.c apue.h 16 $(CC) $(CFLAGS) $(INCLUDE) -c $^ 17 dynamiclibapp.o:dynamiclibapp.c apue.h 18 $(CC) $(CFLAGS) $(INCLUDE) -c $^ 19 20 all:$(OBJS) $(LIB) 21 cd ./dynamiclib && make all 22 $(CC) $(CFLAGS) -rdynamic $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR) 23 在上行,执行编译时并没有加载动态接口函数,而是在应用程序执行时加载的;需要 -rdynamic 选项, 以确保 dlopen 这些接口可用 24 clean: 25 rm -f *.o 26 rm -f $(TARGET) 27 cd ./dynamiclib && make clean
对于这种方式编译出来的动态库文件,不需要在 /etc/ld.so.conf.d/ 目录中配置 libmytest.so 库文件的路径说明
多源码路径Makefile编写
CC = arm-linux-gnueabihf-gcc CXXFLAGS = INC_DIR = ./inc LIB_DIR = ./lib OBJ_DIR = ./obj PPP_DIR = ./ppp WIFI_DIR = ./wifiTARGET = $(LIB_DIR)/libhal.soCFLAGS = -Wall -O -g -fPIC -I$(INC_DIR)SRCS = $(wildcard $(PPP_DIR)/*.c $(WIFI_DIR)/*.c) OBJS = $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(SRCS)))$(TARGET):$(OBJS)$(CC) -shared -fPIC -o $@ $(OBJS)# ppp module $(OBJ_DIR)/%.o:$(PPP_DIR)/%.c $(CC) $(CFLAGS) $(INCLUDE) -o $@ -c $<# wifi module $(OBJ_DIR)/%.o:$(WIFI_DIR)/%.c$(CC) $(CFLAGS) $(INCLUDE) -o $@ -c $<clean:rm -f $(OBJS) $(LIBPATH)$(TARGET)
转载于:https://www.cnblogs.com/aaronLinux/p/8242552.html
[动态库]动态库生成和使用以及Makefile编写相关推荐
- GCC : 什么是编译?什么是静态库?什么是动态库?怎么生成?优先级?
本文旨在让大家真正明白C程序如何运行.库文件的种类区别.如何生成.如何使用等! 一.简介: gcc 最初是 "GNU C Compiler" 的简称,只是当作一个 C 语言的编译器 ...
- linux库引入之动态库静态库(生成和使用)
库: 库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容. 如何使用 用户需要同时具有头文件和库. ...
- Linux-(C/C++)生成并使用静态库/动态库
静态库/动态库概要 在Windows下静态库的后缀为:.lib.动态库后缀为:.dll:而在Linux下静态库的后缀为:.a.动态库的后缀为:.so. 那么什么是静态库呢? 首先我们来看看程序编译的大 ...
- 如何在VS2005下生成动态运行时库
如果我们的工程采用的是动态链接MFC库,那我们的程序如果拷贝到一个没有转VC的电脑中,我们的程序要想正确运行,除了拷贝程序外,还要将运行时库拷贝过去,下面记录下如何创建动态运行时库: file-> ...
- Linux下静态库(.a)和动态库(.so) 的生成与使用
" 很多崩溃其实都发生在安静里,你坐在那里一动不动,内心世界却已经坍塌粉碎,一地狼藉. " 关于库~ 作为开发者应该不陌生~ 经常会生成或使用一些库,包括.a和 ...
- Linux静态库.a与动态库.so的生成与区别、以及.so库文件的封装与使用
#一.前言 如果有公司需要使用你们产品的一部分功能(通过代码调用这些功能),如果不想提供源代码,那么就可以通过封装成库文件的形式提供给对方使用.本文主要介绍了生成动态库与静态库文件的过程.以及封装和使 ...
- 安阳师范学院计算机与信息工程学院吴琴霞,5.甲骨文字形动态描述库及其字形生成技术研究-中国计算机学会中文.PDF...
5.甲骨文字形动态描述库及其字形生成技术研究-中国计算机学会中文.PDF 北京大学学报 ( 自然科学版) Acta Scientiarum Naturalium Universitatis Pekin ...
- Linux系统上库文件的生成与使用(静态库和动态库)
目录 1.什么是库文件? 2.静态库的生成与使用 2.1.生成 .o 文件 2.2.创建静态库 2.3.使用静态库 3.动态(共享)库的生成与使用 3.1.生成 .o 文件 3.2.生成动态库文件 3 ...
- 库文件、静态库(lib)与动态库(dll)的生成与使用
静态库 程序编译一般需经预处理.编译.汇编和链接几个步骤.在应用中,有一些公共代码是需要反复使用,就把这些代码编译为"库"文件:在链接步骤中,连接器将从库文件取得所需的代码,复制到 ...
最新文章
- wps临时文件不自动删除_win10系统下wps残留文件无法删除如何解决
- 【Node】常用基础 API 整理
- 试着翻译24小时自学SQL第四版
- ASP.NET Core开发-Docker部署运行
- 右击菜单一键优化(增加新建office2003、新建reg和bat,删除新建公文包、新建wps、新建rar)...
- Spring Boot————Web应用启动时自动执行ApplicationListener用法
- A. Balanced Substring
- 是什么让你开始劝退的?(@韩冬)
- 3个人的java 实验_20165104-JAVA第三次实验
- A星寻路算法(A* Search Algorithm)
- 用TMG搭建×××服务器(二)---L2TP/IPsec ×××
- systemback慎用:安装后无法启动
- 如何从ST官方获取你需要的单片机原理图和PCB封装
- rocky linux 8.5 基本设置
- 【异常】解决 Cannot find module ‘./element-ui‘ or its corresponding type declarations.
- linux查看隐藏大文件夹,Linux系统隐藏文件/文件夹操作教程
- 荒岛求生html5小游戏在线玩,荒岛求生
- 一元享移动怎么样_移动新套餐:18元享“全免流”+1元1G流量,阿里鱼卡要遭殃?...
- BufferedInputStream。。。。。。。BufferedReader和BufferedWriter
- 正则表达式练习题自带注释