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

时间:2010-10-01 12:07:29

标签: c struct function-pointers

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

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;

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

4 个答案:

答案 0 :(得分:12)

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

为结构命名:

struct pr_PendingResponseItem {

    // some fields required for processing...

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

答案 1 :(得分:8)

有两种方法可以实现 - 对于您的示例结构。它们基本上是同构的。

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

    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;
    
  2. 使用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;
    };
    
  3. 请注意,结构标记与typedef名称位于不同的名称空间中,因此不需要为typedef和结构标记使用不同的名称。另请注意,在C ++中,typedef是不必要的。

答案 2 :(得分:3)

类似这样的事情

typedef struct _pr_PendingResponseItem_ {

    // some fields required for processing...

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

应该修复它。

(经过测试和工作)

答案 3 :(得分:0)

添加上面的nos的答案。

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

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

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