c – C API函数的样式
我正在开发一个支持多种编程环境的库,如VB6和FoxPro.我必须坚持C约定,因为它是最低的共同点.现在我对这个风格有疑问.
假设函数进程输入并返回一个字符串.在此过程中,可能会发生错误.目前提出的风格是这样的: int func(input params... char* buffer,unsigned int* buffer_size); 这种风格的好处是原型中包含了所有内容,包括错误代码.并且可以避免内存分配.问题是该功能非常冗长.并且因为buffer_size可以是任何,所以需要更多的代码来实现. 另一种选择是返回char *,并返回NULL以指示错误: char* func(input params...); 此样式需要调用者删除缓冲区.内存分配是必需的,因此服务器程序可能会面临内存碎片问题. 第二个选项的变体是使用线程局部变量来保存返回的指针char *,这样用户就不需要删除缓冲区. 你喜欢哪种风格?还有原因吗? 解决方法
谈到这个问题,我有点“受损的商品”.我曾经为嵌入式电信设计和维护相当大的API.您不能将任何事情视为理所当然的环境.甚至不是全局变量或TLS.有时甚至堆缓冲区显示实际上是寻址ROM内存.
因此,如果您正在寻找“最低公分母”,您可能还想考虑目标环境中可用的语言结构(编译器可能接受标准C中的任何内容,但如果某些内容不受支持,则链接器会说不. 话虽如此,我总是会选择替代方案1.部分原因是(正如其他人所指出的那样),您不应该直接为用户分配内存(间接方法将进一步解释).即使用户保证使用纯C和纯C,他们仍然可以使用他们自己的自定义内存管理API来跟踪泄漏,诊断日志记录等.通常赞赏支持这样的策略. 在处理API时,错误通信是最重要的事情之一.由于用户可能有不同的方法来处理代码中的错误,因此您应该尽可能地保持整个API中的通信.用户应该能够以一致的方式和最少的代码将错误处理包装到您的API中.我通常总是建议使用清晰的枚举代码或定义/ typedef.我个人更喜欢typedef:ed enums: 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 ); }; 当然,这种结构的风格总是可以进行严肃的辩论. 祝好运! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |