编程之路刚刚开始,错误难免,希望大家能够指出。
假如生成一个动态库A,然后动态库B的生成又调用了动态库A,那么凡是调用了动态库B的程序或者库,需要既链接动态库A也要链接动态库B,这也是动态库最重要的特性,不然就叫静态库了,可以仔细想想下面这段话:
如果将程序链接到共享库,那么链接器就不会把库中的目标模块复制到可执行文件中,而是在可执行文件中写入一条记录,以表明可执行文件在运行时需要使用该共享库。一旦在运行时将可执行文件载入内存,一款名为“动态链接器”的程序会确保将可执行文件所需的动态库找到,并载入内存,随后实施运行时链接,解析可执行文件中的函数调用,将其与共享库中相应的函数定义关联起来。在运行时,共享库代码在内存中只需保留一份。且可供所有运行中的程序使用。 --<<Linux/Unix系统编程手册>>
先来看下目录结构:
直接上所有cpp文件:
1 /* cpci.h */ 2 #include "../ParseDBC/ParseDBCInfo.h" 3 int cpci(); 4 5 /* cpci.cpp */ 6 #include "cpci.h" 7 int cpci() 8 { 9 return ParseDBC()+1; 10 } 11 12 /* ParseDBCInfo.h */ 13 int ParseDBC(); 14 15 /* ParseDBCInfo.cpp */ 16 #include "ParseDBCInfo.h" 17 int ParseDBC() 18 { 19 return 2; 20 } 21 22 /* main.cpp */ 23 #include "cpci.h" 24 #include <stdio.h> 25 int main() 26 { 27 printf("result = %d ",cpci()); 28 29 return 0; 30 }
各目录的Makefile文件(写的有点菜):
1 #顶层目录的Makefile 2 SOURCE = main.cpp 3 4 SUBDIRS = ParseDBC CPCICard 5 6 TARGET = Demo 7 8 all: SUBDIRS_MAKE $(TARGET) 9 10 SUBDIRS_MAKE: 11 @for dir in $(SUBDIRS); do $(MAKE) -C $$dir ; done 12 13 $(TARGET): 14 g++ main.cpp -o $(TARGET) -I./CPCICard -lcpci -L./CPCICard -lParseDBCInfo -L./ParseDBC 15 16 clean: SUBDIRS_CLEAN TARGET_CLEAN 17 18 TARGET_CLEAN: 19 rm -r $(TARGET) 20 21 SUBDIRS_CLEAN: 22 @for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean; done
1 #CPCICard目录的Makefile 2 SOURCE = cpci.cpp 3 4 OBJ = $(SOURCE:.cpp=.o) 5 6 TARGET = libcpci.so 7 8 all:$(TARGET) 9 10 $(OBJ): $(SOURCE) 11 g++ -c $(SOURCE) -I../ParseDBC -lParseDBCInfo -L../lParseDBC 12 13 $(TARGET): $(OBJ) 14 g++ -shared -fPIC -o $(TARGET) $(OBJ) -lParseDBCInfo -L../ParseDBC 15 16 clean: 17 rm -r $(TARGET) $(OBJ)
1 #ParseDBC目录的Mkaefile 2 SOURCE = ParseDBCInfo.cpp 3 4 OBJ = $(SOURCE:.cpp=.o) 5 6 TARGET = libParseDBCInfo.so 7 8 all: $(TARGET) 9 10 $(OBJ): $(SOURCE) 11 g++ -c $(SOURCE) 12 13 $(TARGET): $(OBJ) 14 g++ -shared -fPIC -o $(TARGET) $(OBJ) 15 16 clean: 17 rm -r $(TARGET) $(OBJ)
执行结果:
make
make clean