C函数指针回调为具有“self”引用参数

时间:2015-05-12 08:28:36

标签: c struct function-pointers typedef self-reference


我想创建一个任务结构,其中包含一个指向回调的函数指针来执行所述任务。该任务包含参数,所以我想将结构的“this / self”指针传递给回调执行程序函数。 这创建了循环依赖,我一直在尝试各种前向声明等,但似乎无法正确。我错过了使这个不可能的东西,或者只是我的C语法魔法非常弱。将任务*更改为无效*似乎是在作弊?

在task.h中

// create a function pointer type signature for executing a task
typedef int (*executor) (task* self);

// create a task type
typedef struct {
    executor exec;  // the callback to execute the task
    ... // various data for the task
} task;

3 个答案:

答案 0 :(得分:1)

转发声明struct task,然后使用struct task声明函数指针,然后声明struct task和typedef task

struct task;
typedef int (*executor) (struct task* self);

typedef struct task {
    executor exec;  // the callback to execute the task
    ... // various data for the task
} task;

或者正如Jens所说:

首先typedef task,前向声明为struct task,然后声明函数指针(使用typedef task)和struct task

typedef struct task task;
typedef int (*executor) (task* self);

struct task {
    executor exec;  // the callback to execute the task
    ... // various data for the task
};

答案 1 :(得分:1)

您之前必须添加不完整类型声明,告诉编译器稍后将定义该类型。您可以“滥用”所谓的struct标签具有自己的命名空间,与类型名称分开的事实因此,struct标签名称可以与类型名称相同:

typedef struct task task; // typedef a struct task as "task"
typedef int (*executor) (task* self); // pointer to incomplete type

typedef struct task { // re-use struct tag name here to complete the type
    executor exec;
} task; // typedef a name for the completed type

...
task t;

答案 2 :(得分:0)

Typedef和forward首先声明结构,它应该可以工作,就像那样:

$formats = array(

    // Define the styles that will be available in TinyMCE's dropdown style menu
    // * Use 'selector' to specify which elements a style can be applied to
    // * See Headings example below for explanation of different settings
    // * Using 'classes' allows a class to be combined with others while 'attributes'=>'style' removes other classes before applying
    // Text styles

    array(
        'title' => 'Selected text'
    ),
    array(
        'title' => 'highlight red',
        'classes' => 'red',
        'inline' => 'span',
        'selector' => 'i,em,b,strong,a'
    ),

    array(
        'title' => 'Images',
    ),
    array(
        'title' => 'Put a frame around a photo',
        'attributes' => array('class'=>'framed'),
        'selector' => 'img'
    )
);
//Set the dropdown menu options
HtmlEditorConfig::get('cms')->setOption('style_formats',$formats);