Pergunta

É uma boa idéia para as funções da C API alocar sua saída ou que o usuário especifique o buffer de saída? Por exemplo:

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

Mais especificamente, estou me perguntando por que a API Win32 usa principalmente o segundo caso (por exemplo GetWindowText, LookUpAccountSid). Se uma função da API sabe o tamanho da saída, por que o usuário tenta adivinhar o tamanho da saída? Não consigo encontrar nenhuma informação sobre por que o segundo caso seria usado.

Além disso: o exemplo do LookUpAccountSid é particularmente ruim. Internamente, ele usa a API LSA, que aloca a saída para o chamador. Em seguida, LookUpAccountSid faz com que o usuário aloque um buffer (e adivinhe o tamanho do buffer correto) quando ele pode retornar a saída da LSA! Por quê?

Foi útil?

Solução

A API Win32 não pré-alocada buffers porque deseja fornecer o código de chamada a opção de como fornecer o buffer. Ele permite que eles forneçam pilha e uma variedade de buffers baseados em heap. Existem vários lugares onde o tamanho máximo do buffer é conhecido antes do tempo e os desenvolvedores desejam a simplicidade de usar um buffer baseado em pilha.

O sistema de arquivos é o melhor exemplo, pois os caminhos não excedem MAX_PATH. Então, em vez de alocar + livre. O desenvolvedor simplesmente declara um buffer baseado em pilha.

A vantagem de ter a Memória da API C C é que ela simplifica o padrão de chamada. A desvantagem do padrão Win32 é que, na maioria das vezes, você acaba chamando a API duas vezes. A primeira vez para determinar o tamanho do buffer, depois a segunda vez com um buffer de tamanho apropriado. Com um buffer alocado da API, é necessário apenas uma chamada.

A desvantagem é que você tira a escolha da alocação do chamador. Além disso, você deve comunicar sua escolha para que eles liberem adequadamente a API (o Windows, por exemplo, pode alocar de vários locais diferentes).

Outras dicas

A segunda abordagem tem algumas vantagens como

  • Permite que os chamadores gerenciem a vida útil das alocações de memória
  • Ele permite que os chamadores reutilizem a memória alocada para chamadas diferentes que seguem o mesmo padrão
  • Ele permite que os chamadores decidam qual buffer fornecer EG Stack ou Heap.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top