Linux不同共享库中同名函数的处理

2020-09-28 11:23:33 浏览数 (1)

场景引入:

在一个尚未成熟的行业中,一般行业标准是先于国家标准。这就导致了开发人员需要做很多兼容工作,再就是会用到很多其他厂商提供的库与头文件,面对不同版本的标准,一般会更新库与头文件。那么此时如果要兼容新库和旧库要做怎样的操作呢?

①当两个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

一、小结

当两个共享库中有同名函数时,调用函数顺序取决于链接库顺序。

0 人点赞