API дизайн - выделить выход? - PullRequest
6 голосов
/ 19 января 2010

Является ли хорошей идеей для функций 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 в основном использует второй случай (например, GetWindowText , LookupAccountSid ). Если функция API знает, насколько велик вывод, зачем пользователю пытаться угадать размер вывода? Я не могу найти информацию о том, почему будет использоваться второй случай.

Также: пример LookupAccountSid особенно плох. Внутренне он использует LSA API, который распределяет выходные данные для вызывающей стороны. Затем LookupAccountSid заставляет пользователя выделить буфер (и угадать правильный размер буфера), когда он может просто вернуть вывод из LSA! Почему?

Ответы [ 2 ]

6 голосов
/ 19 января 2010

Win32 API не выделяет буферы заранее, потому что он хочет дать вызывающему коду выбор способа предоставления буфера.Это позволяет им предоставлять стек и различные буферы на основе кучи.Есть несколько мест, где максимальный размер буфера известен заранее, и разработчики хотят простоту использования стекового буфера.

Файловая система - лучший пример, поскольку пути не будут превышать MAX_PATH.Так что вместо того, чтобы выделять + бесплатно.Разработчик просто объявляет основанный на стеке буфер.

Преимущество наличия C API выделяет память в том, что это упрощает шаблон вызова.Недостатком шаблона Win32 является то, что в большинстве случаев вы вызываете API дважды.Первый раз, чтобы определить размер буфера, затем второй раз с буфером соответствующего размера.При использовании буфера, выделенного API, требуется только один вызов.

Недостатком является то, что вы отказываетесь от выбора распределения у вызывающей стороны.Кроме того, вы должны сообщить свой выбор, чтобы они должным образом освободили API (например, окна могут выделяться из нескольких разных мест).

1 голос
/ 19 января 2010

Второй подход имеет некоторые преимущества, такие как

  • Позволяет звонящим управлять временем выделения памяти
  • Это позволяет вызывающим абонентам повторно использовать выделенную память для разных вызовов, которые следуют той же схеме
  • Позволяет звонящим решать, какой буфер для предоставления, например, стек или куча.
...