C/C++中能否修改函数指针实现原有函数前置运行额外逻辑?
实现方案
你的需求可以实现,以下分两种场景提供可运行的方案:
方案1:纯C实现(返回标准C函数指针)
C标准本身没有内置闭包支持,我们通过预分配跳板函数槽位实现,可自定义最大绑定数量:
#include <stdio.h> typedef void (*function_type)(int); // 按需调整最大支持的同时绑定的函数数量 #define MAX_TRAMPOLINE 16 // 存储每个绑定的原始函数和附加函数 static struct { function_type original; void (*additional)(void); } trampoline_slots[MAX_TRAMPOLINE]; // 通用跳板逻辑 static void trampoline_exec(int slot_idx, int num) { trampoline_slots[slot_idx].additional(); trampoline_slots[slot_idx].original(num); } // 批量生成固定槽位的跳板函数 #define DEF_TRAMPOLINE(n) \ static void trampoline_##n(int num) { trampoline_exec(n, num); } DEF_TRAMPOLINE(0) DEF_TRAMPOLINE(1) DEF_TRAMPOLINE(2) DEF_TRAMPOLINE(3) DEF_TRAMPOLINE(4) DEF_TRAMPOLINE(5) DEF_TRAMPOLINE(6) DEF_TRAMPOLINE(7) DEF_TRAMPOLINE(8) DEF_TRAMPOLINE(9) DEF_TRAMPOLINE(10) DEF_TRAMPOLINE(11) DEF_TRAMPOLINE(12) DEF_TRAMPOLINE(13) DEF_TRAMPOLINE(14) DEF_TRAMPOLINE(15) static const function_type trampoline_table[MAX_TRAMPOLINE] = { trampoline_0, trampoline_1, trampoline_2, trampoline_3, trampoline_4, trampoline_5, trampoline_6, trampoline_7, trampoline_8, trampoline_9, trampoline_10, trampoline_11, trampoline_12, trampoline_13, trampoline_14, trampoline_15 }; function_type attachToFunction(function_type original, void (*additional_function)(void)) { // 查找空闲槽位 for (int i = 0; i < MAX_TRAMPOLINE; i++) { if (trampoline_slots[i].original == NULL) { trampoline_slots[i].original = original; trampoline_slots[i].additional = additional_function; return trampoline_table[i]; } } // 超出绑定数量返回空,可自行添加错误处理 return NULL; } // 可选:解绑回收槽位 void detachFunction(function_type bound_func) { for (int i = 0; i < MAX_TRAMPOLINE; i++) { if (trampoline_table[i] == bound_func) { trampoline_slots[i].original = NULL; trampoline_slots[i].additional = NULL; break; } } }
注意事项
- 多线程环境下需要加锁保护槽位的分配与回收
- 不再使用的绑定函数需调用
detachFunction回收槽位,避免资源耗尽
方案2:C++实现(更简洁无绑定数量限制)
如果不需要返回纯C函数指针,仅需要可调用对象,用C++11及以上的std::function实现最优:
#include <functional> #include <cstdio> typedef void (*function_type)(int); // 注意:返回值改为std::function,调用方式和普通函数完全一致 std::function<void(int)> attachToFunction(function_type original, void (*additional_function)(void)) { return [=](int num) { additional_function(); original(num); }; }
如果必须返回兼容C的函数指针,C++环境下也可以直接复用方案1的代码,无需修改。
测试用例
void A(int num) { printf("执行A函数,参数为:%d\n", num); } void C() { printf("先执行C函数\n"); } int main() { // 方案1测试 function_type B = attachToFunction(A, C); if (B) B(123); detachFunction(B); // 方案2测试 auto B2 = attachToFunction(A, C); B2(456); return 0; }
运行输出:
先执行C函数 执行A函数,参数为:123 先执行C函数 执行A函数,参数为:456
内容的提问来源于stack exchange,提问作者Bobi.Liu
相关产品推荐
相关产品推荐

