简体   繁体   English

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

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

I have a problem when using WEAK reference in C. Make assumption, I have the src code structure as follows: 我在C中使用WEAK引用时遇到问题。假设一下,我的src代码结构如下:

//Eclipse C project structure // 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

And: 和:

//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 //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 //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 //dummy_TestWeakAttribute.h

#define static //disable static keyword

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

//weak_test_case.c //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 //strong_test_case.c

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

void test_function_strong(void){
    function();
}

I got the result on the screen: 我在屏幕上得到了结果:

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

I can't use the REAL function anymore. 我不能再使用REAL函数了。 All my making calls to the real test function is impossible because it was declared as __attribute__((weak)) before. 我对真正的test函数的所有调用都是不可能的,因为它之前被声明为__attribute__((weak)) So, Is there anybody having idea on this case ? 那么,有人对此案有想法吗? The main purpose, I'd like to call my real test (in source_sample.c ) but don't remove weak attribute as well. 主要目的是,我想调用我的真实test (在source_sample.c ),但也不要删除 weak属性。

First off, be aware that weak linkage is not a C concept. 首先,请注意,弱链接不是C概念。 It is an ELF concept, at least for our purposes, and GCC (and other compiler) support for it is a C extension. 至少出于我们的目的,这是一个ELF概念,而GCC(和其他编译器)对此的支持是C扩展。 Therefore, little of what I have to say is based on the C standard. 因此,我要说的很少是基于C标准的。 With that said ... 照这样说 ...

Your program has two functions test() , both with weak linkage. 您的程序有两个函数test() ,它们都具有弱链接。 If there were an alternative with strong linkage then that would override both. 如果存在具有紧密联系的替代方案,那么这将覆盖两者。 Since there is not, it is unspecified which of the two is linked to any given reference (call), but it follows from the mechanism of ELF dynamic linking that the same one would would be linked to every reference in any given dynamic object. 由于没有,因此未指定两者中的哪一个链接到任何给定的引用(调用),但是从ELF动态链接的机制可以得出,同一个引用将链接到任何给定的动态对象中的每个引用。

Other than system libraries, you have only one dynamic object in play -- the program -- so it stands to reason that the same implementation of test() is called at every point. 除了系统库之外,您只在运行一个动态对象(即程序),因此可以推断在每个点都调用了相同的test()实现。 It's unclear to me why you suppose it would be otherwise. 我不清楚您为什么会这样认为。 Note in particular that the weird games you are playing with the static keyword are strictly obfuscatory. 特别要注意的是,您使用static关键字玩的怪异游戏完全是混淆性的。 You have no actual static declarations anywhere in the code you present. 您提供的代码中的任何地方都没有实际的static声明。

You indeed could declare a static function test in some file, and in that case you would expect calls to test() from within that file to be linked to the internal static version. 您确实可以在某个文件中声明一个static函数test ,在这种情况下,您希望从该文件中调用test()链接到内部static版本。 To the best of my knowledge, however, a static function cannot also be weak. 据我所知, static函数也不能弱。 That wouldn't make any sense. 那没有任何意义。

The main purpose, I'd like to call my real test (in source_sample.c) but don't remove weak attribute as well. 主要目的是,我想调用我的真实测试(在source_sample.c中),但也不要删除弱属性。

So you want to provide for overriding some references to the function but not others? 因此,您想提供覆盖该函数的某些引用,而不覆盖其他引用吗? Are you nuts? 你疯了吗? What a nightmare that would be to build, and I don't even want to think about maintaining it. 这将是一场噩梦,我什至不想考虑维护它。

If you want to provide a default implementation that you can always call then you cannot make that the weak function. 如果要提供始终可以调用的默认实现,则不能使该函数变弱。 Doing so is inconsistent with always being able to call it. 这样做与始终能够调用它不一致。 You can, however, make it a separate, ordinary function that the weak one calls, and any other function also can call: 但是,您可以使它成为一个单独的普通函数,弱者可以调用它,而其他任何函数也可以调用:

test.h: test.h:

#ifndef TEST_H
#define TEST_H

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

#endif

test.c: test.c的:

#include "test.h"

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

void test(void) {
    test_default();
}

Anyone with access to test_default() can then call it, but whether it gets called as a result of calling test() depends on what version of test() is linked to the call -- it is weak, so a different version could be provided. 任何test_default()访问test_default()都可以调用它,但是调用test()的结果是否被调用取决于该调用链接到了哪个test()版本-它很弱,因此可以使用其他版本提供。

Note also that depending on the scope you want test_default() to have, it might be both possible and sensible to make it static , whereas test() must not be static as long as it is weak. 还要注意,根据您希望test_default()的范围,将它设置为static可能是可行的,而明智的是,只要test()很弱,就不能为static

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM