如何在struct中正确定义一个函数指针,它以struct为指针?

Posted

技术标签:

【中文标题】如何在struct中正确定义一个函数指针,它以struct为指针?【英文标题】:How to properly define a function pointer in struct, which takes struct as a pointer? 【发布时间】:2010-10-01 12:07:29 【问题描述】:

我有一个带有回调函数的结构,回调函数需要一个指向该结构的指针才能执行其操作。如何正确定义这些元素,以便在没有警告的情况下编译?

typedef struct 

    // some fields required for processing...

    int (*doAction)(struct pr_PendingResponseItem *pr);
 pr_PendingResponseItem;

如果我删除 pr 参数上的“struct”属性,我会得到一个错误。如果我把它留在里面,我会收到警告: “它的作用域只是这个定义或声明,可能不是你想要的”

一切正常,但我想知道定义这种结构的正确方法。

同样相关的是定义一个自引用结构:

typedef struct LinkedItem_ 
    LinkedItem_ * prev;
    LinkedItem_ * next;
    void * data;
 LinkedItem;

(我认为这是正确的,但如果与问题相关,欢迎提出其他想法。)

【问题讨论】:

【参考方案1】:

您的函数指针引用了结构 pr_PendingResponseItem,但您尚未声明结构 pr_PendingResponseItem。您只有一个未命名的结构,类型定义为名称 pr_PendingResponseItem(并且该名称尚未建立)。

给结构命名:

struct pr_PendingResponseItem 

    // some fields required for processing...

    int (*doAction)(struct pr_PendingResponseItem *pr);
 ;
typedef struct pr_PendingResponseItem pr_PendingResponseItem;

【讨论】:

【参考方案2】:

有两种方法可以做到这一点 - 对于您的示例结构。它们本质上是同构的。

    使用结构标记,如其他各种答案中所示。

    typedef struct pr_PendingResponseItem
    
        // some fields required for processing...
        int (*doAction)(struct pr_PendingResponseItem *pr);
     pr_PendingResponseItem;
    
    typedef struct LinkedItem
    
        struct LinkedItem *prev;
        struct LinkedItem *next;
        void * data;
     LinkedItem;
    

    使用typedef 为不完整的结构类型命名,并在结构定义中使用typedef

    typedef struct pr_PendingResponseItem pr_PendingResponseItem;
    struct pr_PendingResponseItem
    
        // some fields required for processing...
        int (*doAction)(pr_PendingResponseItem *pr);
    ;
    
    typedef struct LinkedItem LinkedItem;
    struct LinkedItem
    
        LinkedItem *prev;
        LinkedItem *next;
        void * data;
    ;
    

请注意,结构标签与typedef 名称位于不同的命名空间中,因此typedef 和结构标签无需使用不同的名称。另请注意,在 C++ 中,typedef 是不必要的。

【讨论】:

这是唯一真正确定您可以转发声明typedef的答案。【参考方案3】:

类似的东西

typedef struct _pr_PendingResponseItem_ 

    // some fields required for processing...

    int (*doAction)(struct _pr_PendingResponseItem_ *pr);
 pr_PendingResponseItem;

应该修复它。

(测试和工作)

【讨论】:

【参考方案4】:

通过以上没有添加到答案。

这里的关键见解是,在处理像“typedef struct name1 name2;”这样的声明时,您实际上是在声明两种类型,即“struct name1 ;”然后是“typedef struct name1 name2;”,其中“struct name1”是一个类型,你必须使用语法“struct name1”来引用它,并且“ name2" 是一种类型,您将其称为“name2”。您可以省略“name1”,在这种情况下,您只需定义第二种类型,第一种仍然是匿名结构。

现在,在第一种情况下,如果要引用类型“struct pr_PendingResponseItem”,则需要声明该类型,而不是声明的匿名结构。因此,将您的结构声明更改为“struct pr_PendingResponseItem”。

在第二种情况下,您尝试将结构类型引用为前向引用(即在其定义完成之前引用它),这是允许的,但要引用结构类型,所需的语法是“结构名称”。因此,您需要将定义中对“LinkedItem_”的前向引用替换为“struct LinkedItem_”。

【讨论】:

以上是关于如何在struct中正确定义一个函数指针,它以struct为指针?的主要内容,如果未能解决你的问题,请参考以下文章

如何在python的类中正确实现辅助函数

如何在 PHP + MySQL 中正确实现自定义会话持久化器?

如何在.Net中正确实现自定义计时器

如何在Java中正确定义多维通用集合?

如何在 models.py 文件中正确定义 ManyToMany 字段

如何在 Android 中正确定义 2 个主要的启动器活动