在C中使用event_new()函数的Event.h库

时间:2018-07-06 20:16:30

标签: c pointers events

首先,我不是程序员,我从事电气工程。我已经做过一些编程,但是永远不会说我是一个很好的程序员。这个问题可能会被否决,但这没关系,因为我已经尝试了两个月了。

我对event.h一无所知,但是我有一个可以使用并使用它的现有代码。就像这样(我更改了一些内容以隐藏信息,但是代码有效):

struct event_base   *base;
struct event        *read_event;
struct event        *signal_event;

typedef struct sample_ctx {
    sens_handle_t   *sens_handler;
    sens_data_t     data;
} sample_ctx_t;

// signal handler to break the event loop
void
signal_handler(evutil_socket_t sock, short event, void *user_data)
{
    event_base_loopbreak(base);
}

// receive callback
void
sens_recv_cb(evutil_socket_t sock, short event, void *user_data)
{
    static int i = 0;
    int        timeout = 0;

    static struct timeval   timestamp;
    struct timeval          timestamp2;
    struct timeval          diff;
    sens_status_t           status;
    sample_ctx_t            *ctx;

    ctx = (sample_ctx_t *)user_data;

    if (i == 0) {
        gettimeofday(&timestamp, NULL);
        i = 1;
    }
    status = sens_read(&ctx->data, ctx->sens_handler);


    if ((status == SENS_SUCCESS)     &&
       !isnan(ctx->data.info1)  &&
       !isnan(ctx->data.info2)   &&
       !isnan(ctx->data.info3)      &&
       !isnan(ctx->data.info4)) {
        fprintf(stderr, "%lf %lf %lf %lf\n",
                               ctx->data.info1,
                               ctx->data.info2,
                               ctx->data.info3,
                               ctx->data.info4);
        gettimeofday(&timestamp, NULL);
    } else {
        gettimeofday(&timestamp2, NULL);

        timersub(&timestamp2, &timestamp, &diff);

        timeout = diff.tv_sec + (diff.tv_usec / 1000000);

    }
}


int main()
{
int fd;

status_t status;


sample_ctx_t ctx;

memset(&ctx, 0, sizeof(ctx));


status = sensor_open(&fd, &ctx.gps_handler);
if (status != V2X_SUCCESS) {
    fprintf(stderr, "Open failed ... sensor might not be running\n");
    goto deinit_4;
}

base = event_base_new();
if (!base) {
    fprintf(stderr, "Failed to create event base\n");
    goto deinit_3;
}

// register for the read events
read_event = event_new(base, fd, EV_PERSIST|EV_READ, sens_recv_cb, &ctx);
if (!read_event) {
    fprintf(stderr, "Failed to create read event\n");
    goto deinit_2;
}

// register for the SIGINT signal on ctrl + c key combo
signal_event = evsignal_new(base, SIGINT, signal_handler, NULL);
if (!signal_event) {
    fprintf(stderr, "Failed to create signal event\n");
    goto deinit_1;
}

event_add(read_event, NULL);

evsignal_add(signal_event, NULL);

event_base_dispatch(base);

evsignal_del(signal_event);
deinit_1:
    event_free(read_event);
deinit_2:
    event_base_free(base);
deinit_3:
    sensor_close(ctx.sens_handler);
deinit_4:
    return 0;
}

此代码从传感器检索数据并将其打印到屏幕上。它的目的很简单,但是必须完成的方法却很复杂。至少对我来说。

好,所以在sens_recv_cb函数中,ctx->数据被打印到屏幕上,但是我需要在main函数中访问它。唯一调用此函数的时间是main中的event_new函数。有没有办法获取主要数据?就像可以说的,我只想在main中打印ctx-> data.info1,同时仍然在sens_recv_cb函数中打印出以前的所有内容。

在不更改整个代码的情况下我想做些什么?

1 个答案:

答案 0 :(得分:0)

由于mainsens_recv_cb是异步的,因此您将需要一种在它们之间发出信号的方法以及一种回调方法来存储数据。您可以将两者与linked list组合在一起:

struct node {
    sample_ctx_t data;
    struct node *next;
    struct node *previous;
}
struct node *head = NULL;
struct node *tail = NULL;

事件处理程序添加到列表的开头,而main函数将其从结尾删除。这是一个FIFO。在将数据读/写到列表时,您需要使用atomic operations。这些链接提供了您需要了解的内容,如果您进行搜索,则可以在此处和其他站点找到很多示例代码。您可能会在GitHub上找到一个开源的,线程安全的链表实现。

基本上,当列表为空时,main不需要消耗任何东西。