在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
(source_sample.c
},但也不要删除 weak
属性。
答案 0 :(得分:2)
首先,要注意弱连接不是C概念。这是一个ELF概念,至少对于我们的目的而言,GCC(和其他编译器)对它的支持是C扩展。因此,我所说的很少是基于C标准。随着那说......
您的程序有两个函数test()
,两者都具有弱链接。如果有一个具有强联系的替代方案,那么这将覆盖两者。由于没有,因此未指定哪两个链接到任何给定的引用(调用),但是它遵循ELF动态链接的机制,相同的机制将链接到任何给定动态对象中的每个引用。 / p>
除了系统库之外,你只有一个动态对象 - 程序 - 因此可以确保在每个点调用test()
的相同实现。我不清楚为什么你认为不然。请特别注意,您使用static
关键字进行的奇怪游戏是严格混淆的。您所提供的代码中的任何位置都没有实际的static
声明。
您确实可以在某个文件中声明static
函数test
,在这种情况下,您希望从该文件中调用test()
链接到内部{{1}版本。然而,据我所知,static
函数也不能弱。这没有任何意义。
主要目的是,我想调用我的真实测试(在source_sample.c中),但也不要删除弱属性。
所以你想提供覆盖一些函数的引用而不是其他的引用?你疯了吗?这将构成一场噩梦,我甚至不想考虑维持它。
如果您想提供一个可以随时调用的默认实现,那么您无法将其作为弱函数。这样做与始终能够调用它不一致。但是,你可以将它作为一个单独的普通函数,弱函数调用,任何其他函数也可以调用:
static
#ifndef TEST_H
#define TEST_H
void test(void) __attribute__((weak));
void test_default(void);
#endif
有权访问#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()
只要它很弱。