必须设计该系统以使这项工作发挥作用。
有多个方面必须协调:
- 必须有一种方法来更改函数指针。
- 代码必须通过指针调用函数。
有多种方法可以详细地做到这一点,但它们最终会成为主题的变体。
/* Declaration of function pointer used to invoke the function */
extern int (*filename_func_ptr)(int arg1, char const *arg2);
/* Two versions of the function */
extern int filename_func_1_1(int arg1, char const *arg2);
extern int filename_func_1_2(int arg1, char const *arg2);
/* Definition of function pointer - pointing to version 1.1 of the function */
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_1;
/* Use of function pointer */
static void some_function(void)
{
printf("%d\n", (*filename_func_ptr)(1, "pi"));
}
请注意,您可能永远不会在同一个文件中同时拥有filename_func_1_1()
和filename_func_1_2()
声明。我描述的效果是“好像”。
修补后,无论您选择何种方式,结果就像您这样写:
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_2;
您可能会遇到动态加载(dlsym()
、加号dlopen()
等)的问题以获取新符号。这将需要一个文件名供库动态加载,以及一种将函数名转换为指向正确函数的指针的方法。
每个可修补函数都需要通过指针统一调用。这就是允许您替换该功能的原因。考虑一个动态(共享)库是否足够(因为它可能会更简单)。如果您使用固件,则可能没有那么奢侈。
您需要考虑如何处理具有不同接口的多个功能;您会使用此处所示的单个全局变量,还是必须在每次调用时适当转换的通用函数指针类型,或者联合类型,或者持有指针的结构,或者......有很多组织事物的方法.