弱链接的实际应用是什么?

使用特殊的编译器命令可以将符号声明为弱。 根据维基百科:

弱符号是目标文件或动态库中的符号定义,可能会被其他符号定义覆盖

在什么情况下或为什么应用程序需要弱符号? 典型的用例是什么?


弱链接的一种用法是在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目标支持弱符号,在使用GNU汇编器和链接器时也支持a.out目标。

弱属性示例:

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。

链接地址: http://www.djcxy.com/p/73029.html

上一篇: What are practical applications of weak linking?

下一篇: Any reason to overload global new and delete?