我需要创建一个 API,允许我的客户的开发人员使用专有的 C 模块,该模块将作为库发布(想想.lib
或.so
——不是源代码)。
我想让标题尽可能对开发人员友好(所以我不需要这样做),遵循最佳实践并提供带有描述、示例、警告等的评论。
我还应该从业务、技术和普通常识的角度考虑什么?
谢谢!
一种选择是使用(例如)Doxygen 从标头生成 API 文档。显然,您仍然会随代码一起提供文档。
这给你两个好处:
1)您不必太担心应该在“文档中”还是“在标题中的注释中”,因为更改一个与更改另一个一样容易。所以一切都在文档中。
2)用户不太可能首先阅读您的头文件,因为他们可以合理地确信所有感兴趣的内容都在文档中。但即使他们是顽固的“我不信任文档,我阅读代码”类型,他们仍然会看到您希望他们看到的一切。
自动生成的 API 文档的缺点是它们可能是搜索的噩梦,因此 IMO 值得付出额外的努力来编写非常好的“介绍性”文档。这可能是也可能不是生成的 API 文档的一部分,这取决于您喜欢什么。对于小型 API,仅按“逻辑”而不是字母或源顺序列出所有函数,根据它们的用途而不是它们的作用进行描述,可以更容易进入 API 文档。通过“逻辑”,我的意思是首先列出常用的函数,按照客户端调用它们的顺序,将“做相同类型的事情”的替代方法(如套接字的 send 和 sendTo)组合在一起。然后列出不太常用的功能,
该方法的一个主要困难(可能是阻碍因素)是,根据您的组织,您可能有一个文档团队,并且他们可能无法编辑标题。最好的情况是他们复制编辑您所做的事情,然后您进行更改并将其反馈回来。最坏的情况是整个想法停滞不前,因为“只有文档团队应该编写面向客户的文档,并且必须采用标准格式,我们不能让 Doxygen 输出那种格式”。
至于“您还应该考虑什么”-您已经说过您将遵循最佳实践,因此很难添加太多:-)
其他人提到了文档问题,所以我会远离那些:-P。首先,确保你有理智的包括警卫。我个人倾向于喜欢:
FILENAME_20081110_H_
,基本上是全部大写的文件名,然后是完整的日期,这有助于确保它足够唯一,即使树中有另一个具有相同名称的标题。(例如,您可以想象从 2 个不同的 lib 目录中包含的两个 config.h 具有使用CONFIG_H_
或类似的保护,因此会发生冲突。您选择什么并不重要,只要它可能是唯一的。
此外,如果有任何机会在 c++ 项目中使用此标头,请将标头包装在如下块中:
#ifdef __cplusplus
extern "C" {
#endif
/* your stuff */
#ifdef __cplusplus
}
#endif
这将避免一些因名称修改问题而令人头疼的问题,并使他们不必在外部用这些标题包装标题。
请漂亮请确保您不(重新)定义可能在其他任何地方定义的符号。我不只是指标准名称,请在公共标头中声明/定义的所有符号加上特定字符串的前缀,并避免使用任何其他人可能曾经使用过的名称。
在“专业”公开可用的标题中看到太多这样的疯狂之后,我这样说:
typedef unsigned short uchar;
头文件本身应该干净整洁,并且可能接近最小。它应该指向可以找到文档的位置。它可能不应该包含完整的示例(尽管我自己的一些标题会这样做)。它应包括有关版权和许可的基本信息以及作者详细信息。它应该只包含最终用户需要的东西——没有只有开发人员需要的东西。它应该是独立的;它应该包括使其工作所需的任何其他标头(因此用户可以编写' #include "your-header.h"
'并且代码将干净地编译,即使这是它们包含的第一个或唯一的标头)。
补充:标题也应该包含一些基本的版本信息(文件修订号和修改日期,和/或产品发布版本号和发布日期)。这有助于人们查看软件的两个版本——成功的软件不止一次发布。
补充:亚当让我扩展“只有开发人员需要的东西”。这意味着,例如,即使内部函数可能使用某种结构类型,但如果没有外部接口使用该结构类型,那么公共标头不应包含该结构类型的定义。它应该位于未分发的私有标头中(或仅与完整源一起分发)。它不应该污染公共标头。说“只是浪费了一点点空间”很诱人,说的很准确,但如果每个人都浪费一点点空间和时间,那么总的浪费就会变得昂贵。
公共标头的关键在于它应该包含库用户(函数集)需要的所有内容,而不是他们不需要的任何内容。
考虑实际编写单独的文档。我认为 man/info 页面提供了一个很好的例子来说明 API 文档应该是什么样的。
考虑将文档放在网上,除了任何附带的东西,并将 URL 放在标题中。这将允许一些维护程序员在几年后访问文档,即使原件已经丢失。