__attribute __((弱))不使用多个目标文件

时间:2015-10-28 17:36:58

标签: c gcc

我可能理解弱者的错误:

我的情况:

  1. 带有一些弱回调的“物理层”
  2. 实现这些回调的“框架层”,并为应用程序层提供新的WEAK回调
  3. 主要 - 应用层。
  4. phy.h

    Any

    phy.c

    #pragma once
    
    void phyStuff(void);
    
    // new callback for higher layer
    void __attribute__((weak)) phy_cb();
    

    frm.h

    #include <stdlib.h>
    #include <stdio.h>
    #include "phy.h"
    
    // Callback, weak
    void phy_cb() {
        printf("phy_cb, default implementation. BAD!!!\n");
    }    
    
    void phyStuff(void) {
        printf("PHY stuff. Running phy_cb.\n");
        phy_cb();
    }
    

    frm.c

    #pragma once
    #include "phy.h"
    
    void frmStuff(void);
    
    // new callback for higher layer
    void __attribute__((weak)) frm_cb();
    

    的main.c

    #include <stdio.h>    
    #include "phy.h"
    #include "frm.h"
    
    // implement the callback
    void phy_cb() {
        printf("phy_cb, FRM implementation. GOOD\n");
    }    
    
    // Callback, weak
    void frm_cb() {
        printf("frm_cb, default implementation. BAD!!!\n");
    }    
    
    void frmStuff(void) {
        printf("FRM stuff. Running frm_cb\n");
        frm_cb();
    }
    

    现在,如果我编译它......

    #include <stdio.h>
    
    #include "frm.h"
    #include "phy.h"
    
    void frm_cb() {
        printf("frm_cb, APP implementation. GOOD\n");
    }
    
    void main(void) {
        printf("Main.\n");
    
        phyStuff();
        frmStuff();
    }
    

    为什么在这种情况下不会覆盖弱符号?有没有解决方法?

1 个答案:

答案 0 :(得分:1)

您应该将__attribute__((weak))应用于实现,而不是原型:

<强> phy.h

#pragma once

void phyStuff(void);

// new callback for higher layer
void phy_cb();

<强> phy.c

#include <stdlib.h>
#include <stdio.h>
#include "phy.h"

// Callback, weak
__attribute__((weak)) void phy_cb() {
    printf("phy_cb, default implementation. BAD!!!\n");
}    

void phyStuff(void) {
    printf("PHY stuff. Running phy_cb.\n");
    phy_cb();
}

<强> frm.h

#pragma once
#include "phy.h"

void frmStuff(void);

// new callback for higher layer
void frm_cb();

<强> frm.c

#include <stdio.h>    
#include "phy.h"
#include "frm.h"

// implement the callback
void phy_cb() {
    printf("phy_cb, FRM implementation. GOOD\n");
}    

// Callback, weak
__attribute__((weak)) void frm_cb() {
    printf("frm_cb, default implementation. BAD!!!\n");
}    

void frmStuff(void) {
    printf("FRM stuff. Running frm_cb\n");
    frm_cb();
}

<强>的main.c

#include <stdio.h>

#include "frm.h"
#include "phy.h"

void frm_cb() {
    printf("frm_cb, APP implementation. GOOD\n");
}

void main(void) {
    printf("Main.\n");

    phyStuff();
    frmStuff();
}

现在我们得到了理想的结果:

$ gcc main.c phy.c frm.c
$ ./a.out 
Main.
PHY stuff. Running phy_cb.
phy_cb, FRM implementation. GOOD
FRM stuff. Running frm_cb
frm_cb, APP implementation. GOOD

为了更好地了解正在发生的事情,请尝试单独编译源文件并查看每个对象中的符号:

$ gcc phy.c -o phy.o -c
$ gcc frm.c -o frm.o -c
$ gcc main.c phy.o frm.o
$ nm phy.o | grep _cb
0000000000000000 W phy_cb
$ nm frm.o | grep _cb
0000000000000010 W frm_cb
0000000000000000 T phy_cb
$ nm a.out | grep _cb
000000000040052d T frm_cb
0000000000400581 T phy_cb

nm中的“W”表示它是符号。