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
#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干杯,但愿我在几周前遇到类似问题时就知道这一点!