6

C API 函数分配其输出或让用户指定输出缓冲区是个好主意吗?例如:

BOOL GetString(
    PWSTR *String
    );
...
PWSTR string;
GetString(&string);
Free(string);

对比

BOOL GetString(
    PWSTR Buffer,
    ULONG BufferSize,
    PULONG RequiredBufferSize
    );
...
// A lot more code than in the first case

更具体地说,我想知道为什么 Win32 API 主要使用第二种情况(例如GetWindowTextLookupAccountSid)。如果一个 API 函数知道输出有多大,为什么用户要尝试猜测输出大小?我找不到任何关于为什么要使用第二种情况的信息。

另外: LookupAccountSid 示例特别糟糕。它在内部使用 LSA API,为调用者分配输出。然后 LookupAccountSid 让用户分配一个缓冲区(并猜测正确的缓冲区大小),它可以只返回 LSA 的输出!为什么?

4

2 回答 2

6

Win32 API 不会预先分配缓冲区,因为它希望让调用代码选择如何提供缓冲区。它允许他们提供堆栈和各种基于堆的缓冲区。有几个地方可以提前知道缓冲区的最大大小,开发人员希望简单地使用基于堆栈的缓冲区。

文件系统是最好的例子,因为路径不会超过MAX_PATH. 所以而不是分配+免费。开发人员只需声明一个基于堆栈的缓冲区。

让 C API 分配内存的好处是它简化了调用模式。Win32 模式的缺点是大多数时候您最终会调用 API 两次。第一次确定缓冲区的大小,然后第二次用适当大小的缓冲区。使用 API 分配的缓冲区,只需要一次调用。

不利的一面是,您取消了调用者的分配选择。此外,您必须传达您的选择,以便他们正确释放 API(例如,窗口可以从几个不同的地方分配)。

于 2010-01-19T00:51:30.543 回答
1

第二种方法有一些优点,例如

  • 它允许调用者管理内存分配的生命周期
  • 它允许调用者为遵循相同模式的不同调用重用分配的内存
  • 它让调用者决定提供哪个缓冲区,例如堆栈或堆。
于 2010-01-19T00:54:01.487 回答