转自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     需要加上 -fPIC
3 CXXFLAGS =
4 INCLUDE = -I ./inc -I ../comm/inc
5 TARGET = libmytest.so
6 LIBPATH = ./libs/
7
8 vpath %.h ./inc
9
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 -g
3 CXXFLAGS =
4 INCLUDE = -I ./comm/inc -I ./dynamiclib/inc
5 TARGET = dynamiclibapp
6 LIBVAR = -lmytest             指明需要链接动态库 libmytest.so
7 LIBPATH = -L./dynamiclib/libs  指明 libmytest.so 的路径
8 #search paths for errorhandler.c
9 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 -g
3 CXXFLAGS =
4 INCLUDE = -I ./comm/inc -I ./dynamiclib/inc
5 TARGET = dynamiclibapp
6 LIBVAR = -ldl    需要链接 libdl.so 库
7 LIBPATH =
8 #search paths for errorhandler.c
9 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 库文件的路径说明

4. 多源码路径Makefile编写

CC = arm-linux-gnueabihf-gcc
CXXFLAGS =
INC_DIR = ./inc
LIB_DIR = ./lib
OBJ_DIR = ./obj
PPP_DIR = ./ppp
WIFI_DIR = ./wifi TARGET = $(LIB_DIR)/libhal.so CFLAGS = -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)

[动态库]动态库生成和使用以及Makefile编写的更多相关文章

  1. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  2. 生成lua的静态库.动态库.lua.exe和luac.exe

    前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...

  3. c/c++:动态库 静态库 linux/windows 例子 (转)

    作者:吴秦出处:http://www.cnblogs.com/skynet/本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接). C++静 ...

  4. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...

  5. Linux 下动态库 / 静态库(依赖)

    一. 依赖动态库的动态库 libfun.so依赖动态库libtest.so(libfun.so动态库里的函数intnothing()调用了libtest.so里的intmytest()函数),而mai ...

  6. Ribbon2: 创建动态的Ribbon库

    Sam Radakovitz曾在Excel团队博客中发表过一篇文章,介绍了如何创建动态的Ribbon库,即如何通过RibbonX和VBA放置动态的图形图像到功能区库中,在该文中,作者创建了两个库:一个 ...

  7. Linux 静态库&动态库调用

    1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...

  8. Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明

    本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法: 1.添加动态库(直接添加动态库文件.dll,非子项目) 通过qtcreator创建动态库的方法就不在此 ...

  9. gcc 动态编译 动态库路径

    gcc 动态编译(共享库) 动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令优点:体积小,编译快缺点:依赖性高 代码如下: [root@74-82-173-21 ...

随机推荐

  1. 利用eclipse+jdk1.8搭建Java开发环境(超具体的)

    利用eclipse+jdk1.8搭建Java开发环境 转载请声明出处:http://blog.csdn.net/u013067166/article/details/50267003 引言:eclip ...

  2. VC下加载JPG/GIF/PNG图片的两种方法

    转载自:http://blog.sina.com.cn/s/blog_6582aa410100huil.html 仅管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg ...

  3. SharePoint 2013 Step by Step—— How to Upload Multiple Documents in Document Library

    How to Upload Multiple documents in SharePoint 2013,Options to add multiple files in a document libr ...

  4. Python 字符串过滤

    需求: str1 = " """<div class="m_wrap clearfix"><ul class=" ...

  5. zTree变异篇:如何让同级树节点平铺而非垂直显示

    昨天有一个zTree的使用者在实际的项目中有着这样一个特殊的需求,要求同级树节点能够水平显示,根据设定的宽度自动换行,效果图如下所示:   通过在浏览器调试模式下观察其同级节点的css为: 这个dis ...

  6. PowerShell控制台字体设置

    1.打开注册表: HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe 2.找到键 ...

  7. 分布式系统的那些事儿(六) - SOA架构体系

    有十来天没发文了,实在抱歉!最近忙着录视频,同时也做了个开源的后台管理系统LeeCX,目前比较简单,但是后续会把各类技术完善.具体可以点击“原文链接”. 那么今天继续说分布式系统的那些事. 我们现在动 ...

  8. mui做的苹果app生成ipa后放到自己的网站上让人下载安装

    苹果的APP不通过app store的话就只能是要那个$299的企业签名证书了.这个我还不会搞,没有搞过!!! 别人已经帮忙签名好的ipa,自己再传到自己的服务器上让人下载安装,步骤如下: Hbuid ...

  9. STL学习笔记— —无序容器(Unordered Container)

    简单介绍 在头文件<unordered_set>和<unordered_map> 中定义 namespace std { template <typename T, ty ...

  10. 菜鸟学SSH(六)——Spring事务管理

    Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.Tran ...