[动态库]动态库生成和使用以及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编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 11g 大量废连接占满数据
- 下一篇: Vue错误集