一旦在 C 中声明为 WEAK 函数,如何使用 REAL 函数?

How to use REAL function once it is declared as WEAK function in C?

我在C中使用弱引用时遇到问题。假设,我的src代码结构如下:

//Eclipse C项目结构

    drv
     |   dummy      
     |     |  dummy_Test.h
     |     |  dummy_TestWeakAttribute.h
     |   src
     |     |  source_sample.c
     |   test
     |     |  myModules
     |             strong_test_case.c
     |             weak_test_case.c
    test_program.c

并且:

//test_program.c

#include "drv/dummy/dummy_TestWeakAttribute.h"
#include "drv/dummy/dummy_Test.h"

int main() {
    printf("===================\n");
    printf("  Welcome to main  \n");
    printf("===================\n");
                            // Expectation
    test();                 //-->real function
    function();             //-->real function
    test_function_strong(); //-->real function
    test_function_weak();   //-->weak function

    return 0;
}

//source_sample.c

#include "../dummy/dummy_TestWeakAttribute.h"
#include "../dummy/dummy_Test.h"

static void test(void) {
    printf("NOT overridden!\n");
}

static void function(void){

    int a =1;
    a++;
    test();
}

//dummy_Test.h

#ifndef DRV_DUMMY_DUMMY_TEST_H_
#define DRV_DUMMY_DUMMY_TEST_H_

#define static
//definitions

//struct definitions

//dummy functions

static void test(void);
static void function(void);

//global variable definitions

#endif /* DRV_DUMMY_DUMMY_TEST_H_ */

//dummy_TestWeakAttribute.h

#define static //disable static keyword

static void __attribute__((weak)) test(void);

//weak_test_case.c

#include "../../dummy/dummy_TestWeakAttribute.h"
#include "../../dummy/dummy_Test.h"

static void test(void){
    printf("overridden successfully!\n");
}

void test_function_weak(void){
    function();
}

//strong_test_case.c

#include "../../dummy/dummy_Test.h"

void test_function_strong(void){
    function();
}

我在屏幕上得到了结果:

===================
  Welcome to main  
===================
overridden successfully!
overridden successfully!
overridden successfully!
overridden successfully!

我不能再使用 REAL 功能了。我对真正的 test 函数的所有调用都是不可能的,因为它之前被声明为 __attribute__((weak))。那么,有人对这种情况有想法吗?主要目的是,我想调用我的真实 test(在 source_sample.c 中),但 也不要删除 weak 属性。

首先,请注意弱链接不是 C 语言的概念。它是一个 ELF 概念,至少对于我们的目的而言,GCC(和其他编译器)对它的支持是 C 扩展。因此,我要说的很少是基于 C 标准的。话虽如此...

您的程序有两个函数 test(),都具有弱链接。如果有一个具有强联系的替代方案,那么这将覆盖两者。由于没有,因此未指定两者中的哪一个链接到任何给定的引用(调用),但它遵循 ELF 动态链接的机制,即同一个链接将链接到任何给定动态对象中的每个引用。

除了系统库之外,您只有一个动态对象在起作用——程序——因此在每一点调用相同的 test() 实现是理所当然的。我不清楚为什么你认为情况会不同。请特别注意,您使用 static 关键字玩的奇怪游戏是严格混淆的。您提供的代码中的任何地方都没有实际的 static 声明。

您确实可以在某个文件中声明一个 static 函数 test,在这种情况下,您会期望从该文件中调用 test() 链接到内部 static版本。然而,据我所知,static 函数也不能是弱函数。那没有任何意义。

The main purpose, I'd like to call my real test (in source_sample.c) but don't remove weak attribute as well.

所以你想提供覆盖函数的一些引用而不是其他的?你疯了吗?构建起来真是一场噩梦,我什至不想考虑维护它。

如果您想提供一个您可以随时调用的默认实现,那么您不能将其设为弱函数。这样做与始终能够调用它是不一致的。但是,您可以将其设为一个单独的普通函数,由弱函数调用,并且任何其他函数也可以调用:

test.h:

#ifndef TEST_H
#define TEST_H

void test(void) __attribute__((weak));
void test_default(void);

#endif

test.c:

#include "test.h"

void test_default(void) {
    printf("I am the default implementation");
}

void test(void) {
    test_default();
}

任何有权访问 test_default() 的人都可以调用它,但是调用 test() 是否会调用它取决于链接到调用的 test() 的哪个版本 - - 它很弱,所以可以提供不同的版本。

另请注意,根据您希望 test_default() 的范围,将其设置为 static 可能既可行又明智,而 test() 不得 [=14] =]只要弱就行。