前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux共享库控制导出函数

Linux共享库控制导出函数

作者头像
用户5908113
发布2020-10-29 14:39:00
2.4K0
发布2020-10-29 14:39:00
举报
文章被收录于专栏:Pou光明

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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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 :

代码语言:javascript
复制
#################################################################
#                     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"))) 将函数对外隐藏

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档