c - C:将通用输入 arg (void*) 中的函数指针类型转换为特定的 (char*/int *) arg 和/或不同的返回类型、void、int
问题描述
我有特定的数据类型:
typedef struct _A_s { ... } A_t;
typedef struct _B_s { ... } B_t;
我也有特定的功能来操作这些(例如A_t * init_A(); free_A(A_t *); print(A_t *);
等)。
第三个函数通过 avoid *
和函数指针接收任何这些数据结构类型,以便释放和打印其输入。我想保持这个函数通用,因此转换A_t*
为void*
. 但我不确定这将如何与函数指针一起使用。
这是一个粗略的(对不起!)草图:
typedef (void )(*free_generic_t)(void *);
typedef (void )(*print_generic_t)(void *);
void myfunc(
void *object,
free_generic_t free_fn,
print_generic_t print_fn
){
...
print_fn(object);
free_fn(object);
}
我的目标是这样做:
A_t *a = init_A(...);
B_t *b = init_B(...);
myfunc((void *)a, free_A, print_A);
myfunc((void *)b, free_B, print_B);
但gcc
抱怨因为-Werror=incompatible-pointer-types
,我想继续。忽略此警告,程序可以正常工作。
当我做这个类型转换时我有一个 SIGSEGV它工作正常并通过了valgrind
测试:
myfunc(
(void *)a,
(free_generic_t )free_A,
(free_generic_t )print_A
);
问题 1:在上述场景中,将函数类型转换为函数指针,我能走多远?假设输入参数的数量是固定的。也就是说, allprint_A()
只接受 1 个参数,这将是一个指针。
问题 2:当其中一些特定功能return int
和一些什么都没有时,问题变得更加复杂(void
)。我可以调整通用函数指针以return int
适应特定函数的两种风格,即使其中一些返回void
?
更新:当我对函数指针进行类型转换时,我没有得到 SIGSEGV,这是我的错误。我已经编辑了我的帖子。
解决方案
给那些结构
typedef struct _A_s { ... } A_t;
typedef struct _B_s { ... } B_t;
指向释放器函数的指针并将其
A_t * init_A();
分别填充到B_t * init_B();
.
然后你可以为它们编写一个通用的释放器,通过存储的指针间接调用释放器。
// Anything, which is shared between structures
typedef struct _X_s { void (*deallocator)(void *); ... } X_t;
typedef struct _A_s { X_t x; ... } A_t;
typedef struct _B_s { X_t x; ... } B_t;
然后
void deallocate(X_t *x){
x -> deallocator(x);
}
int main(void){
A_t *a = init_A();
B_t *b = init_B();
deallocate((X_t *)a);
deallocate((X_t *)b);
}
请注意,这只是您如何做到这一点的概念。您必须自己制定详细信息并添加有效性检查等。
推荐阅读
- azure - 从 VSCode 部署到 Azure 时出现“403 - 此 Web 应用程序已停止”
- javascript - 子元素的唯一键道具问题
- android-studio - 应用更新 Android Studio 版本名称和版本代码
- keyboard - 如果按下快捷键,如何获取热键定义?
- overflow - 容器滑动时隐藏文本
- python - 销毁项目的密码
- javascript - 如何修复以下代码中的“设置未定义”错误?不和谐.js v13
- python - 按元素对文件夹内的文件进行排序
- javascript - 如何更改这样的 JSON 解析器?
- xcode - 如何摆脱 Xcode 中的错误或重复提交?