C __属性_uu((弱))无法处理多个对象文件

C __属性_uu((弱))无法处理多个对象文件,c,gcc,C,Gcc,我可能理解弱者的一些错误: 我的情况: 带有一些弱回调的“物理层” “框架层”,实现这些回调,并为应用层提供新的弱回调 主应用层 phy.h #pragma once void phyStuff(void); // new callback for higher layer void __attribute__((weak)) phy_cb(); #pragma once #include "phy.h" void frmStuff(void); // new callback for

我可能理解弱者的一些错误:

我的情况:

  • 带有一些弱回调的“物理层”
  • “框架层”,实现这些回调,并为应用层提供新的弱回调
  • 主应用层
  • phy.h

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

    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    frm.c

    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #包括
    #包括“phy.h”
    #包括“frm.h”
    //实现回调
    void phy_cb(){
    printf(“phy_cb,FRM implementation.GOOD\n”);
    }    
    //回调,弱
    无效frm_cb(){
    printf(“frm_cb,默认实现。错误!!!\n”);
    }    
    无效frmStuff(无效){
    printf(“FRM stuff.Running FRM_cb\n”);
    frm_cb();
    }
    
    main.c

    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #包括
    #包括“frm.h”
    #包括“phy.h”
    无效frm_cb(){
    printf(“frm_cb,APP implementation.GOOD\n”);
    }
    真空总管(真空){
    printf(“Main.\n”);
    phyStuff();
    frmStuff();
    }
    
    现在,如果我编译它

    $ gcc main.c phy.c frm.c
    $ ./a.out 
    Main.
    PHY stuff. Running phy_cb.
    phy_cb, default implementation. BAD!!! <--- not expected!
    FRM stuff. Running frm_cb
    frm_cb, APP implementation. GOOD
    
    $gcc main.c phy.c frm.c
    美元/年
    梅因。
    物理的东西。正在运行phy_cb。
    
    phy_cb,默认实现。糟糕 您应该将
    \uuuuuuuuuuuuuuuuuuuu属性((弱))
    应用于实现,而不是原型:

    phy.h

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

    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    frm.c

    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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();
    }
    
    #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 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”表示它是一个弱符号。

    我怀疑,因为
    phy\u cb
    frm\u cb
    phy.c
    frm.c
    中都被声明为弱符号,所以链接器会选择任意符号。将其中一个设置为强(您可能需要添加一个
    #define
    ,以根据文件的包含位置控制是否添加弱符号注释)。啊。好吧,那奏效了。代码很难看,但效果很好。是的,我现在知道了,你只晚了一年左右:PP,但是如果你想要的话,你有要点,很好answer@MightyPork干杯,但愿我在几周前遇到类似问题时就知道这一点!