我最近使用函数指针通过动态库实现了回调注册的功能。 因此,这意味着我传递了一个位于本地堆栈框架上的变量。 库如何在不因违反内存访问而崩溃的情况下访问该变量?
答案 0 :(得分:3)
这不是问题,因为函数本身永远不会存在于堆栈框架中。
假设您有以下代码:
#include <stdio.h>
void (*fptr)(void);
int num;
void g(void) {
printf("Hello, world!\n");
}
int f(void) {
int a = 42;
num = a;
void (*p)(void) = &g;
fptr = p;
}
int main(void) {
f();
printf("%d\n", num);
fptr();
}
在f
中,我们将fptr
和num
都设置为局部变量的 value 。如果我们在a
返回后尝试引用p
或f
,我们会遇到麻烦,但是我们从不这样做。
fptr
不包含p
;它包含&g
,这只是一个常数,恰好是函数g
在内存中的位置。 g
返回后,f
仍然存在于该位置,因为该函数本身不是局部变量。
这就是设置回调时发生的情况;该库中的某处是一个变量,该变量被分配了您传递的函数的地址。