将基于回调/事件的 C API 转换为“非回调”API

问题描述 投票:0回答:1

我正在尝试在 C 中构建二进制格式和 JSON 之间的双向转换(以使映射可编写脚本)。我查看了 13 个 C JSON 解析器,只发现 2 个具有我想要的所有功能。一种是 LGPL,另一种是使用回调。必须将我的代码放入单独的 DLL 中,这样我就不会将 LGPL 与专有代码混合在一起,这很复杂,所以我会首先尝试“回调 API”。

基于回调的 API 看起来像这样(经过大量编辑的代码):

typedef void *(*api_malloc_func)(void *ctx, size_t sz);
/* ... */
typedef struct {
    api_malloc_func malloc;
    /* ... */
} api_config_params;

typedef struct {
    int (* api_on_bool)(void * ctx, int boolVal);
    int (* api_on_int)(void * ctx, long long intVal);
    /* ...*/
    /* "user-defined data", passed to callbacks. */
    void * ctx;
} api_callbacks;

api_handle api_config(const api_callbacks * callbacks, const api_config_params * cfg);

api_status api_parse(api_handle hand, const unsigned char * json, size_t len);

但是我想要/需要的是,让这个 API “看起来像”二进制 API,是这样的:

typedef struct {
    api_malloc_func malloc;
    /* ... */
    /* "user-defined data" */
    void * ctx;
} api_config_params;

api_handle api_config(const api_config_params * cfg);

typedef enum api_type_t {
    api_type_bool,
    api_type_int,
    /* ... */
} api_type_t;

api_type_t api_peek_type(api_config_params* reader);

bool api_read_bool(api_config_params* reader, bool* boolVal);

bool api_read_int(api_config_params* reader, long long* intVal);

/* ... */

自从我上次用 C/C++ 编码以来已经永远了(我现在是一名“Java 程序员”),所以我不知道如何包装回调/基于事件的 API,使其“非-回调/基于事件的”又名“同步”。

那么,我该怎么做呢?理想情况下,不会使代码成为非线程安全的。这可能吗?

注意:我想我可以让二进制 API 使用回调来代替,但这会使其变慢,而且我只关心二进制 API 的速度,而不是 JSON API 的速度。

c callback
1个回答
0
投票

那么,我该怎么做呢?理想情况下,不会使代码成为非线程安全的。这可能吗?

使用基于回调的解析器,几乎没有空间直接在顶部分层基于拉的接口。控制流致力于读取输入和调度事件。回调的执行可能需要任意长的时间并执行任意工作,但您无法在那里运行拉接口,因为解析器在回调返回之前不会到达下一个项目。

但是,您可以在第二个线程中运行基于拉取的 API。使低级推送解析器执行的回调函数将事件排队以供其他线程使用。如有必要,请使用具有固定容量的阻塞队列,以便低级解析器无法在高级拉解析器之前获取超过固定数量的事件。所需的同步会带来一些开销,但尚不清楚这对您来说有多重要。没有什么特别的原因不能保证线程安全,但这涉及到的考虑因素不仅仅是已经描述的交互。

© www.soinside.com 2019 - 2024. All rights reserved.