gpt4 book ai didi

C 库调用用户代码(函数指针与外部符号)

转载 作者:太空宇宙 更新时间:2023-11-04 03:47:59 24 4
gpt4 key购买 nike

我正在实现一个库,出于不同原因需要调用用户代码。

问题:例如,假设我们调用用户代码来加密某些东西(我们让用户这样做有两个原因:也许他会利用算法的硬件实现,或者他可能不想实现加密并只是返回字符串作为它是在通话的那一刻)。

让用户向我传递一个指向“加密”函数的函数指针会更优雅,例如

void (* encrypt_f)(void *ctx, void *dst, void *src, size_t n);
void (* decrypt_f)(void *ctx, void *dst, void *src, size_t n);
void (* set_key_f)(void *ctx, void *key, size_t n);

struct cipher_interface
{
encrypt_f encrypt;
decrypt_f decrypt;
set_key_f set_key;`
};

我将使用类似以下内容从库中调用用户代码:

struct lib_ctx
{
void *usr_ctx;
struct cipher_interface *usr_itf;
/* ... */
};

void lib_function(struct lib_ctx *ctx, ...)
{
/* ... */
if (ctx->usr_itf->encrypt != NULL)
ctx->usr_itf->encrypt(ctx->usr_ctx, ...);
}

使用上述解决方案的用户,如果他不想实现某个功能,他可以在函数指针中存储一个空指针。

另一种解决方案是简单地为用户必须实现的功能留下一些未解析的符号:

void usr_encrypt(void *ctx, void *dst, void *src, size_t n);
void usr_decrypt(void *ctx, void *dst, void *src, size_t n);
void usr_set_key(void *ctx, void *key, size_t n);

struct lib_ctx
{
void *usr_ctx;
/* ... */
};

void lib_function(struct lib_ctx *ctx, ...)
{
/* ... */
usr_encrypt(ctx->usr_ctx, ...);
}

在第二种解决方案中,如果用户不想使用某个功能,它必须至少定义一个空函数来解析符号。

void usr_encrypt(...) {}

我的库是一个网络协议(protocol)库,对用户代码有很多调用,就像这里介绍的那样(例如,hdlc_connection_indication 通知用户 hdlc 连接成功等)

对于这种情况,最好的方法是什么?

最佳答案

我认为前一种方法是最好的方法,即代码将显式函数指针“作为数据”处理。

后一种方法使得在同一个程序中两个(或更多)用户使用同一个库变得非常困难,可能针对不同的上下文,因此处理起来非常烦人。

例如考虑加密网络和磁盘流量,它们可能位于应用程序内两个完全不同的子系统中,但它们可能仍想使用相同的库服务。通过向/从图书馆传递明确的“上下文”,这很容易做到;使用链接级符号魔法,这几乎是不可能的。

关于C 库调用用户代码(函数指针与外部符号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22856803/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com