【发布时间】:2018-11-07 10:46:05
【问题描述】:
这是对this other SO article 已接受答案的后续问题。我认为这本身就是独立的,这就是我发布它的原因。
我正在尝试将不同模块中定义的结构“收集”到 ELF 部分中。我通过 GCC 编译器 __attributes__ 来做这件事。我不确定是什么阻止了它的工作。
有许多关于 SO 的相关问题,我尝试了他们的一些想法,认为我的代码中的一些小问题就是问题所在。例如,this one。
更新(我进一步简化了代码)
#include <stdio.h>
#define INFO_NAME(counter) INFO_CAT(INFO_, counter)
#define INFO_CAT(a, b) INFO_DUMMY() a ## b
#define INFO_DUMMY()
#define DEFINE_INFO(data...) \
const static struct mystruct INFO_NAME(__COUNTER__) \
__attribute((__section__("info"))) \
__attribute((__used__)) = { data } \
struct mystruct
{
char name[255];
int (*on_init) (int num1);
int (*on_do_something) (int num1);
};
extern struct mystruct __start_info[];
extern struct mystruct __stop_info[];
static int _print_number(int x)
{
printf("%d\n", x);
}
DEFINE_INFO(
.name = "mary",
.on_init = _print_number,
.on_do_something = _print_number
);
DEFINE_INFO(
.name = "joe",
.on_do_something = _print_number
);
DEFINE_INFO(
.name = "bob",
.on_do_something = _print_number
);
int main(void)
{
struct mystruct *iter = &__start_info;
for ( ; iter < &__stop_info; ++iter)
{
printf("element name: %s\n", iter->name);
if (iter->on_init != NULL)
{
iter->on_init(1);
}
if (iter->on_do_something != NULL)
{
iter->on_do_something(2);
}
}
return 0;
}
我所看到的:
$ ./a.out
element name: mary
1
2
element name:
element name:
element name:
Segmentation fault (core dumped)
我期望看到的:
$ ./a.out
element name: mary
1
2
element name: joe
2
element name: bob
2
【问题讨论】:
-
“收集”这个词是什么意思?如果这意味着:将变量放在给定部分 - 您还需要在链接描述文件中声明此问题。
-
这意味着将变量放入给定的部分,并使其出现在以
__start_开头的特定数组中。链接描述文件应该是什么样的? -
这是一个非常广泛的主题,您应该阅读:sourceware.org/binutils/docs/ld/Scripts.html BTW 您的宏很难阅读,不需要 IMO。部分的对齐也应该在链接描述文件中完成。宏容易出错,应不惜一切代价避免使用。
-
C 没有任何机制来表示单独声明的对象应该重叠,或者应该像数组的元素一样立即相互跟随。 GCC
__attribute__s 已经在深入研究扩展领域,但是这些对存储布局的期望超出了标准 C 语言的领域。无论您真正想做的是什么,我建议您找到一种不依赖语言扩展的方法。 -
::sigh:: 如果我们知道,我们如何评论。这不是一个疯狂的想法。该问题被标记为 gcc 问题。相关链接:mgalgs.github.io/2013/05/10/…