首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C API函数的风格

C API函数的风格
EN

Stack Overflow用户
提问于 2009-03-09 14:57:46
回答 9查看 1.6K关注 0票数 9

我正在开发一个支持多种编程环境的库,比如VB6和FoxPro。我必须坚持使用C语言,因为它是最小的公分母。现在我有一个关于风格的问题。

假设函数处理输入并返回一个字符串。在此过程中,可能会发生错误。当前建议的样式是:

代码语言:javascript
复制
int func(input params... char* buffer, unsigned int* buffer_size);

这种风格的好处是,原型中包含了所有内容,包括错误代码。并且可以避免内存分配。问题是这个函数相当冗长。因为buffer_size可以是任意的,所以它需要更多的代码来实现。

另一种选择是返回char*,并返回NULL表示错误:

代码语言:javascript
复制
char* func(input params...);

这种风格要求调用者删除缓冲区。内存分配是必需的,因此服务器程序可能会面临内存碎片问题。

第二个选项的变体是使用线程局部变量来保存返回的指针char*,这样用户就不需要删除缓冲区。

你喜欢哪种风格?原因呢?

EN

回答 9

Stack Overflow用户

发布于 2009-03-09 15:32:46

当涉及到这个问题时,我有点“被损坏了”。我曾经为嵌入式电信设计和维护相当大的API。一个你不能认为任何事情都是理所当然的环境。甚至不是像全局变量或TLS这样的东西。有时,甚至堆缓冲区也会出现,实际上是寻址ROM内存。

因此,如果您正在寻找“最小公分母”,您可能还需要考虑在您的目标环境中有哪些语言构造可用(编译器很可能接受标准C中的任何内容,但如果某些内容不受支持,则链接器将拒绝)。

话虽如此,我还是会选择alternative 1。部分原因是(正如其他人所指出的),您永远不应该直接为用户分配内存(下面将解释一种间接方法)。即使用户被保证使用纯C语言,他们仍然可以使用他们自己的自定义内存管理API来跟踪泄漏,诊断日志记录等。

在处理时,错误通信是最重要的事情之一。由于用户可能有不同的方法来处理其代码中的错误,因此您应该在整个API中对这种通信保持尽可能一致。用户应该能够以一致的方式和最少的代码将错误处理封装到API中。我通常推荐使用清晰的枚举代码或定义/typedefs。我个人更喜欢typedef:ed枚举:

代码语言:javascript
复制
typedef enum {

  RESULT_ONE,
  RESULT_TWO

} RESULT;

..because它提供了类型/赋值安全性。

有一个get-last-error功能也很好(但是需要中央存储),我个人只使用它来提供关于已经识别的错误的额外信息。

alternative 1的冗长可以通过像这样的简单复合来限制:

代码语言:javascript
复制
struct Buffer
{
  unsigned long size;
  char* data;
};

那么你的api看起来可能会更好:

代码语言:javascript
复制
ERROR_CODE func( params... , Buffer* outBuffer );

这一策略也为更复杂的机制打开了大门。例如,你必须能够为用户分配内存(例如,如果你需要调整缓冲区的大小),那么你可以提供一种间接的方法:

代码语言:javascript
复制
struct Buffer
{
  unsigned long size;
  char* data;
  void* (*allocator_callback)( unsigned long size );
  void  (*free_callback)( void* p );
};

当然,这种构造的风格总是值得认真讨论的。

祝好运!

票数 9
EN

Stack Overflow用户

发布于 2009-03-09 15:10:25

我更喜欢第一个定义,其中缓冲区和它的大小是传入的。也有例外,但通常您不希望在调用函数后进行清理。然而,如果我分配内存并将其传递给一个函数,那么我知道我必须自己清理。

处理不同大小的缓冲区应该不是什么大问题。

票数 5
EN

Stack Overflow用户

发布于 2009-03-09 15:07:43

如果我必须在显示的两种风格中选择一种,我每次都会选择第一种。第二种风格给你的库的用户提供了一些其他的东西来考虑,内存分配,并且肯定会有人忘记释放内存。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/626567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档