1

在 C 中使用 WEAK 引用时出现问题。假设,我的 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(in source_sample.c) 但也不要删除 weak属性。

4

1 回答 1

2

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

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

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

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

主要目的,我想调用我的真实测试(在 source_sample.c 中),但也不要删除弱属性。

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

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

测试.h:

#ifndef TEST_H
#define TEST_H

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

#endif

测试.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()不要这样做。static

于 2016-04-13T05:37:07.550 回答