31

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

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484610&%3Bidx=1&%3Bsn=fa5d1e7b29bb7472ea33cc29b92faad1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~          公众号—— Pou光明

场景引入:

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

①当两个 C 语言共享库之间有同名函数,链接时会报错么?

②如果不报错,调用的顺序是如何确定的呢?

③如果我想兼容两个库,该如何操作呢? ( 别人的库无法更改函数名、 C++ 可以使用命名空间 )

方法是肯定有的,这次先测试 ①和②效果。

一、 创建两个具有同名函数的共享库

1.  文件目录结构

640?wx_fmt=png

libOne.c 是源文件、 libOne.c 是源文件对应头文件、 libOneTest.h 是对外暴露的接口头文件。还有一个 Makefile 文件。

2.  创建共享库与静态库 Makefile 文件的编写

#################################################################
# 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 ended\n"
$(Target_Dll):$(C_OBJS)
$(CC) -shared $^ -o $@
@echo -e "\n>>>>> Compiling *$(Target_Dll)* sucessfully ended\n"
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INC_CFLAGS) $< -o $@
.PHONY:all clean
clean:
-rm -f $(C_OBJS)
-rm -f $(TARGET)

我一般是当模板用的,没咋研究。。。这些东西改着改着就会了。我喜欢 camke...

3.  libOne.c 源程序

#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.  生成共享库效果

640?wx_fmt=png

两个共享库中有同名函数 myPrintf() ,输出内容不同。

二、 测试共享库

1.  目录结构

640?wx_fmt=png

myAppTest 是程序执行环境

env.sh 内容: export LD_LIBRARY_PATH=.   配置共享库路径为当前路径

2.  Makefile 文件

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 源文件

#include <stdio.h>
#include "libOneTest.h"
#include "libTwoTest.h"


int main()
{
myPrintf();


return 0;
}

4.  程序执行效果

①链接库的顺序为 LIB=-L../lib -lone -ltwo

640?wx_fmt=png

②链接库的顺序为 LIB=-L../lib -l two  -l one

640?wx_fmt=png

一、 小结

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

640?wx_fmt=png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK