使用特殊的编译器指令,符号可以宣布弱 。 根据维基百科 :
弱符号被在目标文件或动态库中的符号定义了可以由其它符号定义覆盖
在什么情况下还是什么应用程序,你需要弱符号? 什么是典型的用例?
使用特殊的编译器指令,符号可以宣布弱 。 根据维基百科 :
弱符号被在目标文件或动态库中的符号定义了可以由其它符号定义覆盖
在什么情况下还是什么应用程序,你需要弱符号? 什么是典型的用例?
一个使用弱联的正在执行在C ++标准可更换的功能。 即:
void *operator new(std::size_t);
void *operator new(std::size_t, std::nothrow_t const &) noexcept;
void *operator new[](std::size_t);
void *operator new[](std::size_t, const std::nothrow_t&) noexcept;
void operator delete(void *) noexcept;
void operator delete(void *, std::nothrow_t const &) noexcept;
void operator delete[](void *) noexcept;
void operator delete[](void *, std::nothrow_t const &) noexcept;
这些都是必须由实现提供的功能,但如果一个程序实现他们则计划实施替代或覆盖实现的版本。 这是很容易通过弱连接实现。
在嵌入式开发,当你有例如中断指针的载体,这是非常方便的,能够使用弱链接获取默认处理程序你不感兴趣的中断。
这是通过定义一个空的处理程序(一次),然后介绍了你需要每个中断指针,这是弱连接到默认的处理器一个新的正确名称的符号。
然后,矢量充满了这些符号,将在同一实际代码的所有点,直到你决定要实现使用相同的(正确的)名其中之一,其,那么你的代码“压倒”的薄弱环节,导致的一个指针安装在中断表的代码。
这通常是C和汇编的某种混合来实现,但用C伪代码,我们可能会碰到这样的:
static void placeholder_isr(void)
{
}
/* Introduce properly-named function pointers, with weak linking.
* NOTE: This syntax is completely fictional as far as I know.
*/
void (*timer1_isr)() = placeholder_isr __attribute("weak linking");
void (*timer2_isr)() = placeholder_isr __attribute("weak linking");
void (*usart1_isr)() = placeholder_isr __attribute("weak linking");
void (*usart2_isr)() = placeholder_isr __attribute("weak linking");
void (*dma1_isr)() = placeholder_isr __attribute("weak linking");
void (*dma1_isr)() = placeholder_isr __attribute("weak linking");
/* Declare the table of interrupt handlers. */
static void (*isr_table)[] = {
timer1_isr,
timer2_isr,
usart1_isr,
usart2_isr,
dma1_isr,
dma2_isr,
} __attribute("isr vector"); /* Attribute to place it where it needs to go. */
然后在需要时,你可以实现自己的功能:
void timer1_isr(void)
{
/* Handler ISR from timer1. */
}
而无需其他任何改变,它“只是工程”。 只要你的名字是上述“支持代码”希望当然是一个。
弱属性促使发射作为一个弱符号,而不是一个全球性的声明。 这是在确定可以在用户代码被覆盖,虽然它也可以与非函数声明被使用库函数主要是有用的。 弱符号支持ELF目标,也为a.out的目标使用GNU汇编器和链接时。
weak属性例子 :
weak.c
extern void foo() __attribute__((weak));
int main() {
if (foo) foo();
}
foo.c的
void foo() {
printf("in foo.\n");
}
strong.c
extern void foo() ;
int main() {
if (foo) foo();
}
编译
$ cc weak.c // Compiles OK
$ cc strong.c // undefined reference to `foo'
当“foo”被宣布为弱,它的定义可以省略,或者通过不同的库替换,具有一种“链接时绑定”。 连接器将在0填补未定义的弱符号。
典型的每天使用情况是内联和模板函数。
例如当编译的这部分代码g++ -shared -fPIC
:
extern void a();
inline void foo() { a(); }
void bar() { foo(); }
void baz() { foo(); }
将有符号bar和baz标记为T(正常)由nm
和Foo将被标记为W -弱。
(E mn -C ./a.out
)
理由:
内联函数和模板可以在报头中定义和通常来源的不同部分定义的多个次,最后只有一个保持活动状态。
如果将未标记为弱,将是多个“foo”的符号碰撞或编译器将无法禁用内联
当你希望能够在你的代码的另一部分覆盖函数定义您通常使用弱链接。 这通常是在指定例如默认错误处理程序,您可以用自定义功能,如果你使用的库覆盖库的情况。