zoukankan      html  css  js  c++  java
  • Makefile 编译动态库文件及链接动态库

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

    文件目录结构如下

    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 库文件的路径说明

  • 相关阅读:
    数据库
    poj上关于回文的题目
    最长上升子序列
    [CodeForces]914D Bash and a Tough Math Puzzle
    [HAOI2011]problem a
    Arc123 D
    [Cnoi2020]线性生物
    [USACO17FEB]Why Did the Cow Cross the Road III P
    ABC 210
    CF1111D Destroy the Colony
  • 原文地址:https://www.cnblogs.com/ljtknowns/p/5647793.html
Copyright © 2011-2022 走看看