gpt4 book ai didi

c - 将额外数据存储在 c 函数指针中

转载 作者:行者123 更新时间:2023-12-02 02:00:50 25 4
gpt4 key购买 nike

假设有一个库函数(不能修改)接受一个回调(函数指针)作为它的参数,它将在未来的某个时间被调用。我的问题:有没有一种方法可以将额外数据与函数指针一起存储,以便在调用回调时可以检索额外数据。该程序在 c 中。

例如:

// callback's type, no argument
typedef void (*callback_t)();

// the library function
void regist_callback(callback_t cb);

// store data with the function pointer
callback_t store_data(callback_t cb, int data);

// retrieve data within the callback
int retrieve_data();

void my_callback() {
int a;
a = retrieve_data();
// do something with a ...
}

int my_func(...) {
// some variables that i want to pass to my_callback
int a;

// ... regist_callback may be called multiple times
regist_callback(store_data(my_callback, a));
// ...
}

问题是因为 callback_t 不接受参数。我的想法是每次生成一小段asm代码填充到regist_callback中,调用的时候可以找到真正的回调和它的数据存入栈(或者一些不用的寄存器),然后跳转到真正的回调回调,在回调中,可以找到数据。

伪代码:

typedef struct {
// some asm code knows the following is the real callback
char trampoline_code[X];
callback_t real_callback;
int data;
} func_ptr_t;

callback_t store_data(callback_t cb, int data) {
// ... malloc a func_ptr_t
func_ptr_t * fpt = malloc(...);

// fill the trampoline_code, different machine and
// different calling conversion are different
// ...

fpt->real_callback = cb;
fpt->data = data;

return (callback_t)fpt;
}

int retrieve_data() {
// ... some asm code to retrive data on stack (or some register)
// and return
}

合理吗?有没有针对此类问题做过的工作?

最佳答案

不幸的是,随着时间的推移,您可能会被越来越多的系统禁止执行您的蹦床,因为执行数据是利用安全漏洞的一种非常常见的方式。

我会首先向库的作者报告错误。每个人都应该知道不要提供没有私有(private)数据参数的回调接口(interface)。

有这样的限制会让我对库是否可重入进行三思。我建议确保您一次只能有一个未完成的调用,并将回调参数存储在全局变量中。

如果您认为该库适合使用,那么您可以通过编写 n 不同的回调蹦床来扩展它,每个回调蹦床都引用它们自己的全局数据,并将其包装在一些管理 API 中。

关于c - 将额外数据存储在 c 函数指针中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17259559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com