在 C 语言中,函数指针作为来自某个库的回调的通常途径是包含一个void*
用户上下文的指针:
void (*fp)(void* ctx);
允许库使用上下文调用回调ctx
.
假设我使用的库在回调中不包含上下文指针。我需要为每个上下文进行一个回调。在 C 中动态分配函数指针以提供回调的最可移植的方法是什么?我怎么能够malloc()
可以从库中调用的函数代码?
例如:
typedef void (*my_fp_t)(char);
my_fp_t fp = (my_fp_t) malloc(sizeof(...));
init_function_ptr(fp, "Hello, there");
my_library_callback(fp);
...
void my_library_callback(my_fp_t fp) {
fp('a'); // prints "Hello, there"
}
假设您希望分配实际的函数代码,而不是函数指针。编写引导加载程序和类似内容时完成此操作的方式:
- 完全确定编译器和 ABI 使用的底层调用约定。您需要确切地知道堆栈帧中的哪些寄存器和/或位置是函数调用和返回时发生的一切。
- 通过在 C 编译器中编写函数并仔细复制/粘贴程序集,或者在汇编程序中手动编写函数来生成汇编代码。
- 将汇编程序翻译为操作码。
- 确保有一块内存可以用来存储数据和执行代码。这也取决于 ABI 和 MMU 设置。
- 了解如何在此自定义段中分配内存。通常涉及一些链接器脚本摆弄和各种非标准关键字。
#pragma __declspec __attribute__
blabla上面加糖。高度特定于编译器。
- 将内存作为原始内存分配给该区域
uint8_t func [n]
数组,包含十六进制的原始 OP 代码。
- 关闭严格别名和其他此类邪恶的指针转换。从对象指针转换为函数指针时,确保编译器具有一些定义良好的非标准扩展。
- 通过调用代码
((func_ptr)func) ()
.
正如您希望看到的那样,这可能是一项艰巨的任务,具体取决于系统。对于使用嵌入式系统编译器的小型微控制器来说,这是很容易实现的。对于 x86 或 PowerPC 等更复杂的系统,使用 gcc 等编译器的情况要小得多。您将依赖于各种不明确的行为,并且代码将完全特定于系统。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)