Linux共享库控制导出函数

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

在上海出差辛勤工作的第三天......

之前的文章介绍了Linux中对共享库中同名函数的处理规则——根据链接库的顺序来确定调用哪个函数。

本次介绍共享库其他一些有意思的性质。

在我们开发过程中,难免会使用到第三方库,而且时不时还需要更新,某些情况下还要兼容不同版本并维护。

按照上次验证的结果,如果两个不同版本库中有同名函数,并且需要兼容,那我们如何确定要调用哪个函数呢?使用链接库的顺序来处理,显然不是一个好办法。【虽然大部分情况下库的函数名称都是不一样的】

再来一个场景,当我们拿到第三方库和头文件,我们还想看下库里面还有哪些其他的函数接口,这时可以使用 nm -D *.so 进行查看。下面以libone.so为例说明,红线部分为我自己定义的函数。

为了解耦函数,会将功能模块拆解成多个函数,但实际暴露给用户的时候可能只有几个。如果想让用户使用nm -D *.so命令查看时只看到封装的几个函数,在编写makefile时可以使用CFLAGS += -fvisibility=hidden  标志,再将给用户的函数名称前加上__attribute__((visibility("default")))即可。

makefile使用CFLAGS += -fvisibility=hidden标志时,会将所有函数全部隐藏,不使用该标志时,默认所有函数全部公开。

gcc 版本4以上可用【未测试】。

测试用例源码:

1. Create shareLib

libOne.h 

#ifndef __LIBONE_API_H__
#define __LIBONE_API_H__


#define OPEN_API_DEFAULT __attribute__((visibility("default")))
#define OPEN_API_HIDDEN __attribute__((visibility("hidden")))
// #define OPEN_API_LIBONETEST


#ifdef __cplusplus
extern "C"
{
#endif


    /*
*名称:测试用例
*描述:
*参数:无
*返回值:0————成功;其他————错误号。
*说明:
*/
    OPEN_API_DEFAULT int myPrintfDefault();


    OPEN_API_HIDDEN int myPrintfHidden();


#ifdef __cplusplus
}
#endif


#endif


libOne.c

#include "libOne.h"


#include <stdio.h>


#define OPEN_API_LIBONETEST_DEFAULT __attribute__((visibility("default")))
#define OPEN_API_LIBONETEST_HIDDEN __attribute__((visibility("hidden")))
// #define OPEN_API_LIBONETEST_SRC


OPEN_API_LIBONETEST_DEFAULT int myPrintfDefault()
{
    printf("Hi , I am is lib One default ! \n");
    return 0;
}


OPEN_API_LIBONETEST_HIDDEN int myPrintfHidden()
{
    printf("Hi , I am is lib One hidden ! \n");
    return 0;
}

Makefile :

#################################################################
#                     PRIVATE PART                              #
#################################################################
APP_STACK_DIR = .
# 内部头文件
INC_CFLAGS += -I $(APP_STACK_DIR)/Inc
# 对外接口目录
#INC_CFLAGS += -I $(APP_STACK_DIR)/Intf
# 动态链接库
#LDFLAGS += -lName  -lName


# 源文件
CSRC += $(APP_STACK_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_STACK_DIR)./appTest/libOne.a
Target_Dll=$(APP_STACK_DIR)./appTest/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)

2. Test Code

如需完成测试工程代码,可在Pou光明公众号后台留言。

3.  __attribute__((visibility("hidden"))) 将函数对外隐藏

欢迎大家关注公众号—— Pou光明

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值