API设计-分配输出?
C API 函数分配其输出或让用户指定输出缓冲区是个好主意吗?例如:
BOOL GetString(
PWSTR *String
);
...
PWSTR string;
GetString(&string);
Free(string);
vs
BOOL GetString(
PWSTR Buffer,
ULONG BufferSize,
PULONG RequiredBufferSize
);
...
// A lot more code than in the first case
更具体地说,我想知道为什么 Win32 API 主要使用第二种情况(例如 GetWindowText,LookupAccountSid)。如果 API 函数知道输出有多大,为什么用户要尝试猜测输出大小?我找不到任何关于为什么使用第二种情况的信息。
另外:LookupAccountSid 示例特别糟糕。它在内部使用 LSA API,为调用者分配输出。然后 LookupAccountSid 让用户在它可以返回 LSA 的输出时分配一个缓冲区(并猜测正确的缓冲区大小)!为什么?
Is it a good idea for C API functions to allocate their output, or to have the user specify the output buffer? For example:
BOOL GetString(
PWSTR *String
);
...
PWSTR string;
GetString(&string);
Free(string);
vs
BOOL GetString(
PWSTR Buffer,
ULONG BufferSize,
PULONG RequiredBufferSize
);
...
// A lot more code than in the first case
More specifically I'm wondering why the Win32 API primarily uses the second case (e.g. GetWindowText, LookupAccountSid). If an API function knows how big the output is, why have the user try to guess the output size? I can't find any information on why the second case would be used.
Also: the LookupAccountSid example is particularly bad. Internally it uses the LSA API, which allocates the output for the caller. Then LookupAccountSid gets the user to allocate a buffer (and guess the correct buffer size) when it could just return the output from LSA! Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Win32 API 不预先分配缓冲区,因为它想让调用代码选择如何提供缓冲区。它允许他们提供堆栈和各种基于堆的缓冲区。有几个地方可以提前知道缓冲区的最大大小,并且开发人员希望能够简单地使用基于堆栈的缓冲区。
文件系统是最好的例子,因为路径不会超过
MAX_PATH
。所以而不是分配+释放。开发人员只需声明一个基于堆栈的缓冲区即可。让 C API 分配内存的优点是它简化了调用模式。 Win32 模式的缺点是大多数时候您最终会调用 API 两次。第一次确定缓冲区的大小,然后第二次使用适当大小的缓冲区。通过 API 分配的缓冲区,只需要一次调用。
但缺点是您剥夺了调用者的分配选择权。此外,您必须传达您的选择,以便他们正确释放 API(例如,Windows 可以从多个不同的位置进行分配)。
The Win32 API does not pre-allocate buffers because it wants to give the calling code the choice of how to provide the buffer. It allows for them to provide stack and a variety of heap based buffers. There are several places where the maximum size of the buffer is known ahead of time and developers want the simplicity of using a stack based buffer.
The file system is the best example as paths won't exceed
MAX_PATH
. So rather than allocate + free. The developer simply declares a stack based buffer.The advantage to having the C API allocate memory is that it simplifies the calling pattern. The downside of the Win32 pattern is that most times you end up calling the API twice. The first time to determine the size of the buffer, then the second time with a buffer of appropriate size. With an API allocated buffer only one call is needed.
The downside though is that you take away the choice of allocation from the caller. Additionally you must communicate your choice in order for them to properly free the API (windows for instance can allocate from several different places).
第二种方法有一些优点,例如
提供例如堆栈或堆的缓冲区。
The second approach has some advantages like
buffer to provide e.g. stack or heap.