这就是我在纯 C 中管理它的方式。
首先,我会将它们打包成一个 32/64 位长的无符号整数,以使它们尽可能紧凑。
第二步,仅在库编译中使用的私有头文件,我将在其中定义一个宏来创建 API 函数包装器和内部函数:
#define CoolFeature1 0x00000001 //code value as 0 to disable feature
#define CoolFeature2 0x00000010
#define CoolFeature3 0x00000100
.... // Other features
#define Cool CoolFeature1 | CoolFeature2 | CoolFeature3 | ... | CoolFeature_n
#define ImplementApi(ret, fname, ...) ret fname(__VA_ARGS__) \
{ return Internal_#fname(Cool, __VA_ARGS__);} \
ret Internal_#fname(unsigned long Cool, __VA_ARGS__)
#include "user_header.h" //Include the standard user header where there is no reference to Cool features
现在我们有一个带有标准原型的包装器,它将在用户定义标题中可用,以及一个内部版本,它保留一个附加标志组以指定可选功能。
使用宏编码时,您可以编写:
ImplementApi(int, MyCoolFunction, int param1, float param2, ...)
{
// Your code goes here
if (Cool & CoolFeature2)
{
// Do something cool
}
else
{
// Flat life ...
}
...
return 0;
}
在上述情况下,您将获得 2 个定义:
int Internal_MyCoolFunction(unsigned long Cool, int param1, float param2, ...);
int MyCoolFunction(int param1, float param2, ...)
如果您正在分发动态库,您最终可以在宏中为 API 函数添加用于导出的属性。
如果宏的定义是在编译器命令行上完成的,您甚至可以使用相同的定义头ImplementApi
,在这种情况下,头中的以下简单定义就可以了:
#define ImplementApi(ret, fname, ...) ret fname(__VA_ARGS__);
最后一个将只生成导出的 API 原型。
当然,这个建议并不详尽。您可以进行更多调整以使定义更加优雅和自动化。即包括一个带有函数列表的子标题,以便仅为用户创建 API 函数原型,以及为开发人员创建内部和 API。