代码之家  ›  专栏  ›  技术社区  ›  wj32

API设计-分配输出?

  •  6
  • wj32  · 技术社区  · 16 年前

    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返回输出时!为什么?

    2 回复  |  直到 16 年前
        1
  •  6
  •   JaredPar    16 年前

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

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

    C API分配内存的好处在于它简化了调用模式。Win32模式的缺点是,大多数情况下,您会两次调用API。第一次确定缓冲区的大小,然后第二次用适当大小的缓冲区。对于分配了API的缓冲区,只需要一个调用。

    但缺点是您从调用者那里取消了分配的选择。此外,您必须传达您的选择,以便他们正确地释放API(例如,Windows可以从几个不同的地方进行分配)。

        2
  •  1
  •   Ariel    16 年前

    第二种方法有一些优势,比如

    • 它允许调用者管理内存分配的生存期
    • 它允许调用者为遵循相同模式的不同调用重用分配的内存。
    • 它让呼叫者决定 提供的缓冲区,例如堆栈或堆。