首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在共享库中导出静态函数和变量

在共享库中导出静态函数和变量
EN

Stack Overflow用户
提问于 2018-05-28 18:41:28
回答 1查看 815关注 0票数 4

到目前为止,我假设C中具有静态链接(即静态函数和静态变量)的对象不会与其他编译单元(即.c文件)中的其他对象(静态或外部链接)冲突,因此我对内部助手函数使用“短”名称,而不是以库名称作为所有对象的前缀。最近,我的库的一个用户由于名称与另一个共享库的导出函数冲突而崩溃。经过调查,我发现我的几个静态函数是共享库的符号表的一部分。因为它发生在几个主要的版本中,我想我遗漏了一些东西(这样一个主要的bug会被注意到并修复)。

我设法将其简化为以下最小示例:

代码语言:javascript
复制
#include <stdbool.h>
#include <stdlib.h>

bool ext_func_a(void *param_a, char const *param_b, void *param_c);
bool ext_func_b(void *param_a);

static bool bool_a, bool_b;

static void parse_bool_var(char *doc, char const *var_name, bool *var)
{
    char *var_obj = NULL;

    if (!ext_func_a(doc, var_name, &var_obj)) {
       return;
    }
    *var = ext_func_b(var_obj);
}

static void parse_config(void)
{
    char *root_obj = getenv("FOO");
    parse_bool_var(root_obj, "bool_a", &bool_a);
    parse_bool_var(root_obj, "bool_b", &bool_b);
}

void libexample_init(void)
{
    parse_config();
}

在目标文件和共享库的符号表中都可以看到静态变量bool_a和静态函数parse_bool_var

代码语言:javascript
复制
$ gcc -Wall -Wextra -std=c11 -O2 -fPIC -c -o example.o example.c
$ objdump -t example.o|egrep 'parse_bool|bool_a'
0000000000000000 l     O .bss   0000000000000001 bool_a
0000000000000000 l     F .text  0000000000000050 parse_bool_var
$ gcc -shared -Wl,-soname,libexample.so.1 -o libexample.so.1.1 x.o -fPIC 
$ nm libexample.so.1.1 |egrep 'parse_bool|bool_a'
0000000000200b79 b bool_a
0000000000000770 t parse_bool_var

我深入研究了C11、Ulrich Drepper的“如何编写共享库”和其他几个解释符号可见性的资源,但我仍然不知所措。为什么bool_aparse_bool_var在动态符号表中结束,尽管它们被声明为static

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-28 18:46:25

nm输出的第二列中的小写字母表示它们是本地的(如果它们是大写的,情况就不同了)。这些符号不会与相同名称和AFAIK的其他符号冲突,基本上只用于调试目的。本地符号也不会进入动态符号表(可使用nm -D打印,但只能在共享库中),并且它们与非动态符号( nm输出的第二列中的大写字母)一起是可strip格式的。

(您将从Drepper的《如何编写共享库》中了解到,您可以使用-fvisibility=(default|hidden) (不应使用protected)和可见性属性来控制可见性。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50564516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档