精华内容
下载资源
问答
  • weak函数
    2021-03-30 22:45:57

    使用 GNU GCC __attribute__((weak)) 属性修饰的函数,在链接时可以被同名的函数覆盖掉。
    但发现现在的 GNU LD 的 search 规则是有变化的,如果先找到了 static library 里的 weak symbol,就优先 link 此 symbol,而不去 search static library 里是否有 strong symbol.
    这样看上去 weak function 就不生效了。
    那如何让其在 static library 里能够生效呢?可以使用 --whole-archive link option,意味着要包含 static library 里所有的 symbol,这样 LD 就会search 到 strong symbol,但又会有副作用:whole-archive 是把所有的symbol link 到最终的 binary,不管该 symbol 是否有使用,这就增加了最终 binary 的大小。

    更多相关内容
  • 在C编程中,有时候需要写一些weak函数,用来给用户进行覆盖。 之前写NRF的函数的时候,写了一个__weak void NRF_Receive_Callback(uint8_t * data,int len); 用来给用户重载接收回调函数。然后我在main中,重新写了...

    ctime:2019-12-08 12:24:17 +0900|1575775457

    标签(空格分隔): 技术 编程


    在C编程中,有时候需要写一些weak函数,用来给用户进行覆盖。

    之前写NRF的函数的时候,写了一个__weak void NRF_Receive_Callback(uint8_t * data,int len);

    用来给用户重载接收回调函数。然后我在main中,重新写了一个NRF_Receive_Callback,在IAR中编译、工作正常,NRF接收到
    数据之后,会调用main中的callback。然而我用arm gcc编译之后,却发现不行,调用的还是原来的weak函数。在网上搜了半天,
    有一篇文章说到:

    多次试验和搜索,应该就是静态库的函数只有在要被用到的时候,才会被link,但weak symbol相对比较特殊,会先link到weak的function,然后再去找strong的function。因此strong的function实现在静态库里面,并且对应.o里函数也没被其他.o call 到,整个静态库都不会被link进去,因此最后只会选weak function。

    应对的方式

    A:利用—whole-archive和—no-whole-archive强制静态库被link进去,这样strong函数一定会被收到。缺点是如果lib之间有同名function会打出build error

    B:和A类似,利用link选项-u强制某个function被link,但lib和function较多时不好用

    作者:612F

    链接:https://www.jianshu.com/p/be55f46b0e5e

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    想了一下确实是,main中的函数都没被其他文件调用,都是他调用别人。

    因为对makefile不太熟,我没去修改makefile的编译 链接选项了,直接把回调写到其他文件中,如control.c,测试正常,果然是这个问题。

    本文首发于:http://huangzzk.info

    展开全文
  • Weak函数宏定义声明

    千次阅读 2019-08-15 11:33:32
    Weak函数宏定义声明 //WEAK_FUN(int, func_name, int a, int b, int c); #define WEAK_FUN(type,name,args...) \ type __##name(args){return 0;}\ type name(args)__attribute__((weak, alias("__"#name))) ....

    Weak函数宏定义声明 编译器为GCC

    //WEAK_FUN(int, func_name, int a, int b, int c);
    #define WEAK_FUN(type,name,args...) \
    		type __##name(args){return 0;}\
    		type name(args)__attribute__((weak, alias("__"#name)))
    

    示例代码

    //WEAK_FUN(int, func_name, int a, int b, int c);
    #define WEAK_FUN(type,name,args...) type __##name(args){return 0;} type name(args)__attribute__((weak, alias("__"#name)))
    WEAK_FUN(void, f1, void);
    WEAK_FUN(int, f2, int a);
    WEAK_FUN(int, f3, int a, char b);
    WEAK_FUN(int, f4, int a, char b, short c);
    int main(int argc, char **argv)
    {
    	f1();
    	f2();
    	f3();
    	f4();
    	return 0;
    }
    

    使用 gcc x.c -E -o x.i展开宏

    void __f1(void){return 0;} void f1(void)__attribute__((weak, alias("__""f1")));
    int __f2(int a){return 0;} int f2(int a)__attribute__((weak, alias("__""f2")));
    int __f3(int a, char b){return 0;} int f3(int a, char b)__attribute__((weak, alias("__""f3")));
    int __f4(int a, char b, short c){return 0;} int f4(int a, char b, short c)__attribute__((weak, alias("__""f4")));
    int main(int argc, char **argv)
    {
     f1();
     f2();
     f3();
     f4();
     return 0;
    }
    
    展开全文
  • __weak函数

    千次阅读 2017-11-25 22:31:53
    __weak函数用于定义变量或者函数,常见于定义函数,在MDK ARM链接时优先链接定义为非weak的函数或变量,如果找不到则再链接weak函数。具体用法为: file1.c __weak void weakFunction(void){ //do something ...

    1. 使用方法

    __weak函数用于定义变量或者函数,常见于定义函数,在MDK ARM链接时优先链接定义为非weak的函数或变量,如果找不到则再链接weak函数。具体用法为:

    file1.c

    __weak void weakFunction(void){
        //do something
        return;
    }
    
    
    void someFunctionCall(void){
        //do something
        weakFunction();
        //do something
        return;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    file2.c

    void weakFunction(void){
        //do something
        return;
    }
     
    • 1
    • 2
    • 3
    • 4

    具体方法可以参考MDK ARM中的help,本文主要讲的是应用过程中遇到的一个问题。


    2. 问题

    测试环境为:

    MDK-ARM version:5.21a
    MCU: stm32L431RCT6
    compiler cmd:–c99 -c –cpu Cortex-M4.fp -D__MICROLIB -g -O0 –apcs=interwork –split_sections
    -IC:/Users/Administrator/Desktop/weakTest/RTE

    创建一个工程如下:
    在weakTest.c中定义一个weak函数,并且定义一个调用该weak函数的函数

    __weak void weakFunctioin(void){    //定义为__weak类型的函数
        logInfo("print weakFunction\r\n");
    }
    
    int weakFunctionTest(unsigned int tst){
    
    
        logInfo("print A\r\n");
        if (tst) {
            logInfo("print B\r\n");
            weakFunctioin();    //调用函数
            logInfo("print C\r\n");
        }else{
            logInfo("print D\r\n");
        }
        logInfo("print E\r\n");
        return 0;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在main.c文件中,定义main函数及weakFunctionTest函数:

    void weakFunctioin(void){    //定义为正常的函数
    
        logInfo("print nonWeakFunction\r\n");
        return;
    }
    
    int main(void){
    
    
        logInit(logLevelDebug);
        logInfo("Build @ %s %s,system start\r\n", __DATE__, __TIME__);
    
        weakFunctionTest(1);
        logInfo("Build @ %s %s,system stop\r\n", __DATE__, __TIME__);
        while(1);
        return 0;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行时打印为:

    -I: Build @ Jun 12 2017 15:14:18,system start
    -I: print A
    -I: print B
    -I: print nonWeakFunction
    -I: print C
    -I: print E
    -I: Build @ Jun 12 2017 15:14:18,system stop

    此时运行正常,但是如果我修改weakTest.c文件中weak类型的函数weakFunctioin,添加一个死循环:

    __weak void weakFunction(void){
        logInfo("print weakFunction\r\n");
        while(1);
        return;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5

    此时打印为

    -I: Build @ Jun 12 2017 15:14:46,system start
    -I: print A
    -I: print B
    -I: print nonWeakFunction
    -I: print D //ERROR ERROR ERROR
    -I: print E
    -I: Build @ Jun 12 2017 15:14:46,system stop

    本应打印-I: print C的位置成了-I: print D,可见程序运行都已经错乱。而且看样子是编译工具出的问题。


    3. 解决方法

    将带有死循环的weak类型weakFunctionTest函数放在第三个文件中即可。官方论坛的回答是因为优化的原因。

    转载自:http://blog.csdn.net/baicaiaichibaicai/article/details/73129417

    展开全文
  • 加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。...
  • C语言之__weak函数前缀

    万次阅读 2018-06-20 11:28:33
    __weak是一个宏,和__packed是同一种东西都是gcc的扩展属性:#define __packed __attribute__((packed))#define __weak __attribute__((weak))如果这个关键字用在函数定义上面,一般情况下和一般函数没有两样。...
  • it.c中的函数包含进去,因为该文件中只有异常和中断处理函数,没有任何地方显式地调用了该文件中的任何函数,而startup_stm32f10x_md.s中又提供了相应的异常与中断处理函数,虽然被声明为weak属性,但没有被正确覆盖...
  • 学习理解函数加上weak后的变化
  • 加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。...
  • 在使用keil的时候,在定义外部用户函数注册接口的时候 使用了 attribute((weak)) 将外部用户接口暴露出来,然后正常来说用户只需要根据要求对应的实现这个接口即可,但在keil下即使定义了当前接口,编译器也直接跳过...
  • 有这么一种使用场景,一个新时代农民工要做一种库给别人使用 默认帮助客户实行了一套逻辑,按照码农自己的理解搬砖需要自己用手搬 比如 void 搬砖(){ std::cout <...__weak void 搬砖(){ std::cout &...
  • c语言中weak的作用

    千次阅读 2021-05-25 00:55:08
    c语言中weak的作用转载参考至:https://blog.csdn.net/q251900...在u-boot源码中看到__weak关键字,在移植过程中遇到了问题。...u-boot中的weak关键字:__weak用例:int __weak fpga_loadbitstream(int devn...
  • 1,uboot中函数定义前面__weak的符号意味着此函数可以在自己的函数中重定义,也可以使用默认值
  • MDK ARM中weak关键字的使用与中断服务函数问题现象问题原因解决方法之一 问题现象 #define DEMO_LPUART_IRQHandler LPUART1_IRQHandler 对于RT1052中断服务函数,发现串口1中断服务没有编译,中断也无法进入。 void ...
  • weak实现原理

    2021-12-07 19:48:40
    weak 实现原理 下面的一段代码是我们在开发中常见的weak的使用 - (void)viewDidLoad { [super viewDidLoad]; NSObject *obj = [[NSObject alloc] init]; __weak NSObject *weakp = obj; } 汇编 runtime调用objc...
  • linux中__weak关键字

    2021-05-12 15:24:37
    在linux的驱动代码中经常可以看到__weak去修饰一个函数或者变量,大多是用来修饰函数。它的作用有两个:1.weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为**“弱函数”*...
  • __weak是一个宏,和__packed是同一种东西都是gcc的扩展属性: #define __packed __attribute__((packed)) ...但是当有一个同名函数但是不带__weak被定义时,所有对这个函数的调用都是指向后者(不带__wea...
  • rtt之weak

    2021-07-10 18:42:30
    但遇到一个关于它的问题,rtt在调用时,调用了weak声明的函数,而没有调用cubemx自动生成的函数,这样就没有启动设备的时钟,造成工作不正常,要不是一步步仿真,才发现此问题,这种问题不好找,也不太能想到。...
  • ARM 之十一__weak 和 __attribute__((weak)) 关键字的使用

    千次阅读 多人点赞 2020-06-17 19:53:19
    之前对于 __weak 关键字一直是一个简单的认知:编译器自动使用没有 __weak 的同名函数(如果有的话)替换有 __weak 关键字的同名函数,__weak 函数可以没有定义,且编译器不会报错! 至于这个参数详细的使用细节一直...
  • 关于HAL中的__weak详解

    2021-09-25 15:09:55
    最近在使用STM32的hal库进行开发的时候,看到很多库自带的函数有很多是使用__weak修饰的 例如:__weak void function(…) 第一次看到这种写法,很是好奇,那么这个修饰符的作用是什么呢?其实在英语中,weak的意思...
  • linux中__weak关键字的作用

    千次阅读 2018-10-30 09:15:57
    在linux的驱动代码中经常可以看到__weak去修饰一个函数或者变量,大多是用来修饰函数。 它的作用有两个: 1.weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数...
  • C++ weak

    2019-08-05 15:16:49
    在Linux开发环境中,有强符号和弱符号,符号简单来说就是函数、变量的名字,对于全局(非局部、非static)的函数和变量,能不能重名是有一定规矩的,强、弱符号就是针对这些全局函数和变量来说的。 符号类型 ...
  • gcc reference里提到:...A function with this attribute has its name emitted as a weak symbol instead of a global name. This is primarily for the naming of library routines that can be overridden by use
  • 何为__weak? keil5中的修饰符 先看一个源码 /** * @brief Rx Transfer completed callback. * @param huart UART handle. * @retval None */ __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {...
  • MDK ARM中__weak关键字的使用

    万次阅读 2017-06-14 18:28:58
    __weak函数用于定义变量或者函数,常见于定义函数,在MDK ARM链接时优先链接定义为非weak的函数或变量,如果找不到则再链接weak函数。具体用法为: file1.c __weak void weakFunction(void){ //do something ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,938
精华内容 21,975
关键字:

weak函数

友情链接: ACE_tutorial.rar