本文为原创文章,转载请指明该文链接

文件目录结构如下

 dynamiclibapp.c
Makefile
comm/inc/apue.h
comm/errorhandle.c
dynamiclib/Makefile
dynamiclib/dynamiclib_add.c
dynamiclib/dynamiclib_mul.c
dynamiclib/inc/dynamiclibs.h
dynamiclib/libs/

1. dynamiclib目录

dynamiclib/inc/dynamiclibs.h 文件内容如下:

 #ifndef __dynamic_libs_h__
#define __dynamic_libs_h__ #include "apue.h"
int dynamic_lib_func_add(int i1, int i2);
int dynamic_lib_func_mul(int i1, int i2); #endif

dynamiclib/dynamiclib_add.c 文件内容如下:

 #include "dynamiclibs.h"

 int dynamic_lib_func_add(int i1, int i2)
{
int iret = i1 + i2;
printf("... in .so func, %d add %d,return %d\n", i1, i2, iret);
return iret;
}

dynamiclib/dynamiclib_mul.c 文件内容如下:

 #include "dynamiclibs.h"

 int dynamic_lib_func_mul(int i1, int i2)
{
int iret = i1 * i2;
printf("... in .so func, %d multiplys %d, retun %d\n", i1, i2, iret);
return iret;
}

dynamiclib/Makefile 文件内容如下:

 CC       = gcc
CFLAGS = -Wall -g -O -fPIC     需要加上 -fPIC
CXXFLAGS =
INCLUDE = -I ./inc -I ../comm/inc
TARGET = libmytest.so
LIBPATH = ./libs/ vpath %.h ./inc OBJS = dynamiclib_add.o dynamiclib_mul.o
SRCS = dynamiclib_add.c dynamiclib_mul.c $(OBJS):$(SRCS)
$(CC) $(CFLAGS) $(INCLUDE) -c $^ all:$(OBJS)
$(CC) -shared -fPIC -o $(TARGET) $(OBJS)    需要加上 -shared -fPIC
mv $(TARGET) $(LIBPATH) clean:
rm -f *.o
rm -f $(LIBPATH)*

以上文件,就可以生成动态库文件 libmytest.so,应用程序以两种方式加载动态库函数,如下

2. 在编译应用程序时加载动态库

dynamiclibapp.c 文件内容如下:

 #include "apue.h"
#include "dynamiclibs.h" int main(int argc, char *argv[])
{
err_msg("step in main\n");
dynamic_lib_func_add(, );
dynamic_lib_func_mul(, );
err_msg("step out main\n"); return ;
}

Makefile 文件内容如下:

 CC       = gcc
CFLAGS = -Wall -O -g
CXXFLAGS =
INCLUDE = -I ./comm/inc -I ./dynamiclib/inc
TARGET = dynamiclibapp
LIBVAR = -lmytest             指明需要链接动态库 libmytest.so
LIBPATH = -L./dynamiclib/libs  指明 libmytest.so 的路径
#search paths for errorhandler.c
vpath %.c ./comm
#下行是为依赖项 apue.h 准备的,比如 [errorhandler.o:errorhandler.c apue.h] 里的 apue.h
vpath %.h ./comm/inc OBJS = errorhandler.o dynamiclibapp.o
#下行的 apue.h,可以不必写出来
errorhandler.o:errorhandler.c apue.h
$(CC) $(CFLAGS) $(INCLUDE) -c $^
dynamiclibapp.o:dynamiclibapp.c apue.h
$(CC) $(CFLAGS) $(INCLUDE) -c $^ all:$(OBJS) $(LIB)
cd ./dynamiclib && make all
$(CC) $(CFLAGS) $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR)
   在上行中,在执行编译时,加载了 libmytest.so 中函数
clean:
rm -f *.o
rm -f comm/inc/*.gch
rm -f $(TARGET)
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 库文件的绝对路径,例如:

 /home/lijiangtao/dynamiclib/libs

如果不在编译应用程序时加载动态库文件里的函数,而是改为在应用程序执行时(比如:程序的main函数启动期

间,或在程序执行期间)加载 libmytest.so 里函数,那么就可以不需在 /etc/ld.so.conf.d/ 目录中配置 libmytest.so

路径,具体如下所述。

3. 在应用程序执行时加载动态库

dynamiclibapp.c 文件内容如下:

 #include "apue.h"
#include "dynamiclibs.h"
#include <dlfcn.h> typedef int (*fp_lib_add)(int, int);
typedef int (*fp_lib_mul)(int, int);
typedef void* dlhandle; dlhandle dll = NULL;
fp_lib_add func_add = NULL;
fp_lib_mul func_mul = NULL; dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul); int main(int argc, char *argv[])
{
char *pso = "/home/lijiangtao/dynamiclib/libs/libmytest.so";//指定 .so 路径
dll = load_dynamic_func(pso, &func_add, &func_mul);//程序执行时,加载动态函数
err_msg("step in main\n");
func_add(, );//执行 add 函数
func_mul(, );//执行 mul 函数
err_msg("step out main\n"); return ;
} dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul)
{
if(NULL == psopath ||'\0' == psopath[])
return NULL;
char *perrormsg = NULL;
dlhandle dllhandle = dlopen(psopath, RTLD_LAZY);
if(NULL == dllhandle)
{
printf("%s\n", dlerror());
return NULL;
}
if(NULL != padd)
{
*padd = dlsym(dllhandle, "dynamic_lib_func_add");//加载 add 函数
perrormsg = dlerror();
if(NULL != perrormsg)
printf("%s\n", perrormsg);
}
if(NULL != pmul)
{
*pmul = dlsym(dllhandle, "dynamic_lib_func_mul");//加载 mul 函数
perrormsg = dlerror();
if(NULL != perrormsg)
printf("%s\n", perrormsg);
}
return dllhandle;
}

Makefile 文件内容如下:

 CC       = gcc
CFLAGS = -Wall -O -g
CXXFLAGS =
INCLUDE = -I ./comm/inc -I ./dynamiclib/inc
TARGET = dynamiclibapp
LIBVAR = -ldl    需要链接 libdl.so 库
LIBPATH =
#search paths for errorhandler.c
vpath %.c ./comm
#下行是为依赖项 apue.h 准备的,比如 [errorhandler.o:errorhandler.c apue.h] 里的 apue.h
vpath %.h ./comm/inc OBJS = errorhandler.o dynamiclibapp.o
#下行的 apue.h,可以不必写出来
errorhandler.o:errorhandler.c apue.h
$(CC) $(CFLAGS) $(INCLUDE) -c $^
dynamiclibapp.o:dynamiclibapp.c apue.h
$(CC) $(CFLAGS) $(INCLUDE) -c $^ all:$(OBJS) $(LIB)
cd ./dynamiclib && make all
$(CC) $(CFLAGS) -rdynamic $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR)
   在上行,执行编译时并没有加载动态接口函数,而是在应用程序执行时加载的;需要 -rdynamic 选项,
      以确保 dlopen 这些接口可用
clean:
rm -f *.o
rm -f $(TARGET)
cd ./dynamiclib && make clean

对于这种方式编译出来的动态库文件,不需要在 /etc/ld.so.conf.d/ 目录中配置 libmytest.so 库文件的路径说明

Makefile 编译动态库文件及链接动态库的更多相关文章

  1. Makefile 编译静态库文件及链接静态库

    本文为原创文章,转载需指明该文链接 1.代码目录结构如下: comm/ comm/inc/apue.h  3 atexit.c Makefile  5 staticlib/lib/ staticlib ...

  2. 由动态库文件dll生成lib库文件(手动生成.def文件,然后使用lib命令编译,非常牛),同理可使用dll生成.a库文件

    本文基于OpenBlas的编译和安装,来说明如何从一个dll文件生成lib库文件. 参考OpenBlas的说明“Howto generate import library for MingW”,和Mi ...

  3. rpm安装找不到.so库文件(linux动态库连接的相关知识)(转)

    1.找不到库文件的原因 库文件不存在 这种情况一般是因为所需要的包没装,只要安装相应的包就可以解决 存在而系统不知道 这种情况一般出现在自己编译软件时候 确保库文件所在的路径已加入系统,在/etc/l ...

  4. 由动态库文件dll生成lib库文件

    本文基于OpenBlas的编译和安装.来说明怎样从一个dll文件生成lib库文件. 參考OpenBlas的说明"Howto generate import library for MingW ...

  5. 使用makefile编译多个文件(.c , .cpp , .h等)

    有时候我们要一次运行多个文件,这时候我们可以使用Makefile!!! ◊make是什么? make是一个命令工具,是一个解释makefile中指令的命令工具.它可以简化编译过程里面所下达的指令,当执 ...

  6. 利用caffe自带的Makefile编译自定义so文件

    1.文件目录结构 caffe-root |--include |--example |--modules |--test.h |--test.cpp |--python |--src |--tools ...

  7. 将.lib库文件转换成.a库文件的工具

    分享如下两个链接: 微盘: http://vdisk.weibo.com/s/ztzPTJIC52mz2 百度云盘: http://pan.baidu.com/s/11gTOc 使用方法,解压文件mi ...

  8. Eclipse·如何关联Git库文件和添加JUint库

    Eclipse创建工程并关联到文件(SVN或Git管理的代码文件) 新建java工程,用于存放工程的一些信息,默认存放地址. 工程相关的信息是不需要提交到(SVN或Git)版本库的,所以工程存放到本地 ...

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

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

随机推荐

  1. 很轻很强大:轻量级桌面环境比较(转自linuxeden)

    这天你终于下定决心购买了一台流行的 Netbook ,与往常装机一样,直接安装心爱的 Linux 发行版.好不容易安装完成了,却发现平日启动飞快的应用程序在 Netbook 上怎么都跑不快.怎么办呢? ...

  2. PHP 多个mysql连接的问题

    今天在同一个php进程中用mysql_connect新建了两个mysql句柄,这两个句柄都连接同一台数据库,只不过操作的数据库dbname不同,假设这两个句柄分别是$dbhA和$dbhB,它们对应的数 ...

  3. 浅谈 JavaScriptCore

    来源:XcodeMen(王瑞华) 链接:http://t.cn/RVqQI5p 本文由我们团队的王瑞华童鞋撰写. OS X Mavericks 和 iOS 7 引入了 JavaScriptCore 库 ...

  4. Java IDE选择,常用Java IDE排行榜

    Java IDE众多,java开发主要用.最多用.国内较流行.本人常用的java IDE如下: 开发java大项目的IDE一般都用eclipse或netbeans(几乎我所在的公司都是在用eclips ...

  5. Sublime Text 2搭建Go开发环境(Windows)

    转自:http://blog.csdn.net/love_se/article/details/7754274 下载packcontrol包地址:http://www.imjeff.cn/blog/6 ...

  6. Android中实现下拉刷新

    需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新: 思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息 ...

  7. Linux内核(11) - 子系统的初始化之内核选项解析

    首先感谢国家.其次感谢上大的钟莉颖,让我知道了大学不仅有校花,还有校鸡,而且很多时候这两者其实没什么差别.最后感谢清华女刘静,让我深刻体会到了素质教育的重要性,让我感到有责任写写子系统的初始化. 各个 ...

  8. 群智能优化算法-测试函数matlab源码

    群智能优化算法测试函数matlab源代码 global M; creatematrix(2); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %画ackley图. %%%% ...

  9. tag标签数据库的设计

    方案一: 一个表,里面有个tags字段,存放以空格或逗号分隔的标签.缺点是长度受限,tag个数受限,查询like ‘%abc%’效率低 方案二: 同方案一,支持全文索引,或者用Lucence索引查询 ...

  10. PCIe调试心得_DMA part2

    作者:East  FPGA那点事儿 上一章讲述了PCIe总线DMA的原理和XAPP1052存在的问题. 本章以服务器常用的4通道1000M以太网卡为例讲述如何提高DMA的效率. 1.内存重分配Wind ...