场景引入:
在一个尚未成熟的行业中,一般行业标准是先于国家标准。这就导致了开发人员需要做很多兼容工作,再就是会用到很多其他厂商提供的库与头文件,面对不同版本的标准,一般会更新库与头文件。那么此时如果要兼容新库和旧库要做怎样的操作呢?
①当两个C语言共享库之间有同名函数,链接时会报错么?
②如果不报错,调用的顺序是如何确定的呢?
③如果我想兼容两个库,该如何操作呢?(别人的库无法更改函数名、C 可以使用命名空间)
方法是肯定有的,这次先测试①和②效果。
一、创建两个具有同名函数的共享库
1. 文件目录结构
libOne.c是源文件、libOne.c是源文件对应头文件、libOneTest.h是对外暴露的接口头文件。还有一个Makefile文件。
2. 创建共享库与静态库Makefile文件的编写
代码语言:javascript复制#################################################################
# PRIVATE PART #
#################################################################
APP_TEST_DIR = .
# 内部头文件
INC_CFLAGS = -I $(APP_TEST_DIR)/Inc
# 对外接口目录
INC_CFLAGS = -I $(APP_TEST_DIR)/Intf
# 动态链接库
#LDFLAGS = -lName -lName
# 源文件
CSRC = $(APP_TEST_DIR)/Src/*.c
C_OBJS = $(patsubst %.c,%.o,$(wildcard $(CSRC)))
# 动态库编译标志
DEBUG = y
ifeq ($(DEBUG),y)
DEBUG_CFLAGS = -DDEBUG
DEBUG_CFLAGS = -g
endif
CFLAGS = -c
CFLAGS = -Os
CFLAGS = -Wall
CFLAGS = -fPIC
#CFLAGS = -fvisibility=hidden #隐藏属性
CFLAGS = $(DEBUG_CFLAGS)
# 目标文件
Target_Lib=$(APP_TEST_DIR)./Lib/libOne.a
Target_Dll=$(APP_TEST_DIR)./Lib/libone.so
TARGET = $(Target_Lib) $(Target_Dll)
# 编译规则
all:$(TARGET)
$(Target_Lib):$(C_OBJS)
$(AR) rcs $@ $^
@echo -e "n>>>>> Compiling *$(Target_Lib)* sucessfully endedn"
$(Target_Dll):$(C_OBJS)
$(CC) -shared $^ -o $@
@echo -e "n>>>>> Compiling *$(Target_Dll)* sucessfully endedn"
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INC_CFLAGS) $< -o $@
.PHONY:all clean
clean:
-rm -f $(C_OBJS)
-rm -f $(TARGET)
我一般是当模板用的,没咋研究。。。这些东西改着改着就会了。我喜欢camke...
3. libOne.c源程序
代码语言:javascript复制#include "libOne.h"
#include <stdio.h>
// #define OPEN_API_LIBONETEST_SRC __attribute__((visibility("default")))
#define OPEN_API_LIBONETEST_SRC
OPEN_API_LIBONETEST_SRC int myPrintf()
{
printf("Hi , I am is lib One ! n");
return 0;
}
define OPEN_API_LIBONETEST_SRC __attribute__((visibility("default")))后面再做介绍。
4. 生成共享库效果
两个共享库中有同名函数myPrintf(),输出内容不同。
二、测试共享库
1. 目录结构
myAppTest是程序执行环境
env.sh内容:export LD_LIBRARY_PATH=. 配置共享库路径为当前路径
2. Makefile文件
代码语言:javascript复制TARGET=appTest
########CC=g
#CC=arm-linux-gnueabi-gcc
CFLAG=-g -Wall
INCLUDE=-I../include
SRC = main.c
LIB=-L../lib -lone -ltwo
all:
$(CC) $(CFLAG) $(INCLUDE) $(SRC) $(LIB) -o $(TARGET)
3. main.c源文件
代码语言:javascript复制#include <stdio.h>
#include "libOneTest.h"
#include "libTwoTest.h"
int main()
{
myPrintf();
return 0;
}
4. 程序执行效果
①链接库的顺序为LIB=-L../lib -lone -ltwo
②链接库的顺序为LIB=-L../lib -ltwo -lone
一、小结
当两个共享库中有同名函数时,调用函数顺序取决于链接库顺序。