一旦在 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] =]只要弱就行。
我在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] =]只要弱就行。