在这个主题上,我有点“受损”。以前我设计和维护嵌入式电信的相当大的API。这种情况下,您不能将任何东西视为理所当然。甚至像全局变量或TLS这样的东西也不行。有时甚至会出现堆缓冲区,实际上是寻址ROM内存。
因此,如果您正在寻找“最低公共分母”,您可能还需要考虑目标环境中可用的语言结构(编译器可能接受标准C中的任何内容,但如果某些内容不受支持,则链接器会说不)。
话虽如此,我总是会选择替代方案1。部分原因是(正如其他人指出的那样),您永远不应该直接为用户分配内存(间接方法将在后面进一步解释)。即使用户保证使用纯粹和简单的C,他们仍然可能使用自己定制的内存管理API来跟踪泄漏、诊断记录等。通常欣赏支持这样的策略。
错误通信是处理API时最重要的事情之一。由于用户可能具有处理代码中错误的不同方式,因此您应该尽可能一致地在整个API中进行此通信。用户应能够以一致的方式且最少的代码包装向您的API传达错误处理。我通常始终建议使用清晰的枚举代码或定义/typedef。我个人更喜欢typedef:了的枚举:
typedef enum {
RESULT_ONE,
RESULT_TWO
} RESULT;
因为它提供了类型/赋值安全性。
拥有一个 get-last-error 函数也很好(需要中央存储),我个人仅用它来提供关于已识别错误的额外信息。
通过像这样创建简单的复合词,可以限制替代方案1的冗长:
struct Buffer
{
unsigned long size;
char* data;
};
那么你的API可能会更好看:
ERROR_CODE func( params... , Buffer* outBuffer );
这种策略还可以打开更复杂的机制。例如,如果您需要调整缓冲区大小,则必须能够为用户分配内存,那么可以提供一种间接方法:
struct Buffer
{
unsigned long size;
char* data;
void* (*allocator_callback)( unsigned long size );
void (*free_callback)( void* p );
};
当然,这种结构的风格总是存在严重的争议。
祝你好运!