C - 在库的公共头文件中公开第 3 方数据结构

git-bruh

我正在编写一个包含 REST API 的库,并且表示一些数据需要使用 C 标准库中不可用的数据结构,例如哈希映射,因此在内部我使用 3rd 方库来实现它们。现在我想在响应结构中公开它们,我想出了几个解决方案:

  1. 只需按原样公开类型并添加对第 3 方库的依赖,并使用户调用适当的 API 函数(例如hashmap_lib_get(users, "key")获取值):
// header.h (Include guards excluded)
#include <hashmap_lib.h>

struct api_response {
    int field1;
    char *field2;
    HASHMAP_LIB_HM *users; // Map of users to their email. (example)
};

问题:需要额外的用户干预,如果使用通用宏实现库,问题就更大。

  1. 将类型公开为结构内的空指针,并为所有适当的函数编写重复的包装器:
// header.h
struct api_response {
    int field1;
    char *field2;
    void *users; // Don't touch
};

char *api_hashmap_get(void *hm, const char *key);

的内部实现api_hashmap_get只是return hashmap_lib_get((HASHMAP_LIB_HM *) hm, key);

问题:需要重复各种函数定义并需要使用空指针。

这个问题在图书馆中通常是如何解决的?如果两个库彼此“相关”(例如使用事件系统libevent来处理用户的应用程序),第一个解决方案就会有意义,但在这种情况下,它只是关于通用数据结构,因此没有意义对我来说,因为用户也会将其他库用于相同类型的数据结构。

约翰·博林格

我会以不同的方式描述优缺点。:

  • 选项 1将第三方库的 API 合并到您自己的 API 中。谨慎处理这个问题既有技术上的原因,也有法律上的原因。

    • 在技​​术方面,您更难打破对第三方库的依赖。
    • 此外,您将 API 绑定到第三方库的特定版本或版本范围。解决这个问题的最好方法可能是提供另一个库的副本,但这会带来它自己的问题。
    • 在法律方面,可能会对您的库的许可产生影响,具体取决于第三方库的许可。例如,如果 3p 库是根据 LGPL 许可的,那么仅仅动态链接到它并不要求您的库在 GPL 兼容许可下获得许可,但是将其部分或全部 API 合并到您自己的 API 中可能会引入这样的要求。
  • 选项 2涉及提供您自己的 API 来操作第三方数据结构,并要求您放弃一些类型安全。另一方面,它将您的用户与 3p 库隔离。

你在评论里说

我想要关于改进选项 2 的建议,因为它感觉太冗长了。

,但是如果您不打算让用户通过他们的本地方式访问第三方数据结构,那么您别无选择,只能提供您自己的方式。如果您想将您的客户端与第三方库隔离,那么它必须表现为包装器函数。但是,您不必包装整个第三方 API,也不必将包装器表示为第三方函数/宏的直接类似物。

但也有这样的:

  • 选项 3:使您自己的结构对您图书馆的客户不透明。这将要求您为您支持的所有类型的访问提供合适的函数,因此在这方面为您做更多的工作,但它允许您声明结构成员(仅供内部使用),但您认为这是最自然的。另外,所有访问都通过函数而不是其中的一些函数可能会感觉更一致。这使您可以轻松更改结构的细节,而不会破坏库的客户端。

    面向客户端的标头可能如下所示:

    struct api_response; // members not declared
    
    int api_get_field1(const struct api_response *resp);
    const char *api_get_field2(const struct api_response *resp);
    const char *api_get_user_email(const struct api_response *resp, const char *user);
    // ...
    

    这将由仅提供(至少)完整定义的内部、非分布式标头补充struct api_response

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章