You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中向函数传递代码块?以绘图命令为例

在C语言中传递代码块到函数的实现方案

在C语言里,你要实现的“传递任意代码块到函数执行”的需求,回调函数是标准且可行的方案,你之前尝试没成功大概率是回调的参数或类型定义没处理好。结合Allegro库的场景,下面给你具体实现:

1. 定义回调函数类型

首先定义通用的回调类型,用void*传递绘图所需的自定义参数(因为不同绘图命令需要的参数不一样,比如文本需要字体、内容,圆形需要半径、坐标):

typedef void (*DrawCallback)(void* callback_data);

2. 实现通用的draw函数

这个函数负责完成切换buffer、执行绘图逻辑、恢复环境、刷新显示的固定流程:

void draw_to_buffer(ALLEGRO_BITMAP* buffer, ALLEGRO_DISPLAY* disp, DrawCallback callback, void* callback_data) {
    // 保存当前的目标位图
    ALLEGRO_BITMAP* original_target = al_get_target_bitmap();
    
    // 切换到buffer绘图
    al_set_target_bitmap(buffer);
    
    // 执行传入的绘图代码块(回调函数)
    if (callback != NULL) {
        callback(callback_data);
    }
    
    // 恢复原来的目标位图
    al_set_target_bitmap(original_target);
    
    // 清屏、绘制buffer到显示、刷新
    al_clear_to_color(al_map_rgb(0, 0, 0));
    al_draw_bitmap(buffer, 0, 0, 0);
    al_flip_display();
}

3. 封装具体的绘图逻辑为回调

针对不同的绘图需求,把逻辑封装成符合回调类型的函数,比如:

示例1:绘制文本的回调

先定义文本所需的参数结构体:

typedef struct {
    ALLEGRO_FONT* font;
    ALLEGRO_COLOR color;
    float x;
    float y;
    int flags;
    const char* text;
} TextDrawData;

void draw_text_callback(void* data) {
    TextDrawData* text_data = (TextDrawData*)data;
    al_draw_text(text_data->font, text_data->color,
                 text_data->x, text_data->y, text_data->flags,
                 text_data->text);
}

示例2:绘制圆形的回调

定义圆形的参数结构体:

typedef struct {
    float x;
    float y;
    float radius;
    ALLEGRO_COLOR color;
} CircleDrawData;

void draw_circle_callback(void* data) {
    CircleDrawData* circle_data = (CircleDrawData*)data;
    al_draw_circle(circle_data->x, circle_data->y, circle_data->radius,
                   circle_data->color, 2.0f);
}

4. 调用通用draw函数

在主逻辑里,你可以这样调用,实现不同的绘图需求:

// 假设已经初始化了buffer、disp、font
TextDrawData text_data = {
    .font = font,
    .color = al_map_rgb(255, 255, 255),
    .x = 100,
    .y = 100,
    .flags = ALLEGRO_ALIGN_CENTRE,
    .text = "Hello Allegro"
};
// 绘制文本
draw_to_buffer(buffer, disp, draw_text_callback, &text_data);

// 绘制圆形
CircleDrawData circle_data = {
    .x = 200,
    .y = 200,
    .radius = 50,
    .color = al_map_rgb(255, 0, 0)
};
draw_to_buffer(buffer, disp, draw_circle_callback, &circle_data);

关键说明

  • 回调函数的核心是把可变的绘图逻辑和固定的buffer切换、刷新流程解耦,完全符合你减少重复代码的需求。
  • void*参数是C语言里实现通用回调的常用方式,用来传递任意类型的参数结构体,适配不同绘图命令的需求。
  • 如果你的回调不需要额外参数,callback_data可以传NULL,对应的回调函数里直接忽略这个参数即可。

内容的提问来源于stack exchange,提问作者1toneboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:35:12