我正在實現一個庫,需要根據不同的原因調用用戶代碼。例如,假設我們調用用戶代碼來加密某些東西(我們讓用戶這樣做有兩個原因:也許他會利用算法的硬件實現或者他可能不想實現密碼學,只是在調用的時刻返回字符串)。C庫調用用戶代碼(函數指針vs外部符號)
更優雅讓用戶給我一個函數指針的「加密」功能,例如
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(...) {}
我的圖書館是一個網絡協議庫,並有很多的電話像這裏提出的那些用戶代碼(例如hdlc_connection_indication通知有關HDLC連接成功,用戶等)
它是什麼這種情況下的最佳方法?
是的,可能使用函數指針。給他們每個人一個客戶端數據。用客戶端數據註冊客戶端功能。 –