来自不兼容指针类型的 C 指针数组赋值

标签 c arrays function pointers struct

我有以下代码:

struct DataBase {
    union manip_types *manip;
};

union manip_types{
    void ( *man_insert )( struct DataBase *, struct auto_increment *, enum db_insert_types,... );
    void ( *man_remove )( struct DataBase *, struct auto_increment *, enum db_remove_types, int );
    void ( *man_update )( struct DataBase *, enum db_update_types, int,... );
    union db_query_union ( *man_query )( struct DataBase *, enum db_query_types, int );
    struct db_query_extended ( *man_query_ex )( struct DataBase *, struct auto_increment *, enum db_query_types,... )
};

然后我做了:

db->manip = malloc( 5 * sizeof( union manip_types ) );
    db->manip[ 0 ].man_insert = &db_insert;
    db->manip[ 1 ].man_remove = &db_remove;
    db->manip[ 2 ].man_update = &db_update;
    db->manip[ 3 ].man_query = &db_query;
    db->manip[ 4 ].man_query_ex = &db_query_ex;

上面的代码为每个 [0, 1, -> 4] 生成以下警告

Assignment from incompatible pointer type.

函数原型(prototype):

void db_insert( struct DataBase *db, struct auto_increment *a_i, enum db_insert_types db_insert_type,... )
void db_remove( struct DataBase *db, struct auto_increment *a_i, enum db_remove_types db_remove_type, int removeId )
void db_update( struct DataBase *db, enum db_update_types db_update_type, int upId,... )
union db_query_union db_query( struct DataBase *db, enum db_query_types db_query_type, int queryId )
struct db_query_extended db_query_ex( struct DataBase *db, struct auto_increment *a_i, enum db_query_types db_query_type,... )

我应该修改什么?我如何调用该指针数组?例如,v[4]。

最佳答案

您可以声明一个通用函数指针数组,而不是尝试使用这样的 union 数组,例如:

void (*manip[5])();

或者,如果您想动态分配数组:

void (**manip)() = malloc(5 * sizeof( void(*)() ));

并将所有函数指针转换为泛型类型void(*)():

manip[0] = (void(*)()) &db_insert;
manip[1] = (void(*)()) &db_remove;
manip[2] = (void(*)()) &db_update;
manip[3] = (void(*)()) &db_query;
manip[4] = (void(*)()) &db_query_ex;

当然,要调用这些函数,您需要将它们转换回正确的类型,例如:

void (*update)(struct DataBase *, enum db_update_types, int, ...)
   = (void (*)(struct DataBase *, enum db_update_types, int, ...)) manip[2];
update(db, type, n, etc);

为了可读性和可维护性,您可能希望将这些函数签名键入为更具可读性,例如:

typedef void ( *man_insert_t )( struct DataBase *, struct auto_increment *, enum db_insert_types,... );
typedef void ( *man_remove_t )( struct DataBase *, struct auto_increment *, enum db_remove_types, int );
typedef void ( *man_update_t )( struct DataBase *, enum db_update_types, int,... );
typedef union db_query_union ( *man_query_t )( struct DataBase *, enum db_query_types, int );
typedef struct db_query_extended ( *man_query_ex_t )( struct DataBase *, struct auto_increment *, enum db_query_types,... );

让你简单地写

man_update_t update = (man_update_t) manip[2];
update(db, type, n, etc);

或者甚至只是:

((man_update_t) manip[2])(db, type, n, etc);

当然,在实践中,正确的解决方案是将数组替换为结构体,这样您就可以避免所有这些类型转换技巧:

struct db_manip {
    void ( *insert )( struct DataBase *, struct auto_increment *, enum db_insert_types,... );
    void ( *remove )( struct DataBase *, struct auto_increment *, enum db_remove_types, int );
    void ( *update )( struct DataBase *, enum db_update_types, int,... );
    union db_query_union ( *query )( struct DataBase *, enum db_query_types, int );
    struct db_query_extended ( *query_ex )( struct DataBase *, struct auto_increment *, enum db_query_types,... );
};

struct db_manip *manip = malloc(sizeof(struct db_manip));
manip->insert = &db_insert;
manip->remove = &db_remove;
manip->update = &db_update;
manip->query = &db_query;
manip->query_ex = &db_query_ex;

关于来自不兼容指针类型的 C 指针数组赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40935914/

相关文章:

c - 字符串复制中的段错误

在 Typescript 中转换日期类型

arrays - 如何在 Redux 状态下保持秩序?

javascript - 简单的无名 json 数组转换为映射的 JS 或 PHP 数组

java - 在 Java 中从 Postgres 加载非物化数组

objective-c - 将 ObjC id<Protocol> 和类型对象转换为 C 指针 (void *) 然后将其转换回去是否安全?

c - 将用户空间代码移植到内核空间

function - 宏定义和函数定义的区别

javascript - 将数组作为参数传递给函数

javascript - 制作一个jquery函数来返回元素