2010-01-19 6 views
5

Est-ce une bonne idée que les fonctions de l'API C allouent leur sortie ou que l'utilisateur spécifie le tampon de sortie? Par exemple:Conception de l'API - allouer la sortie?

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 

Plus précisément, je me demande pourquoi l'API Win32 utilise principalement le second cas (par exemple GetWindowText, LookupAccountSid). Si une fonction API connaît la taille de la sortie, pourquoi l'utilisateur essaie-t-il de deviner la taille de la sortie? Je ne trouve aucune information sur la raison pour laquelle le second cas serait utilisé.

En outre: l'exemple LookupAccountSid est particulièrement mauvais. En interne, il utilise l'API LSA, qui alloue la sortie à l'appelant. LookupAccountSid obtient alors l'utilisateur pour allouer un tampon (et deviner la taille de mémoire tampon correcte) quand il pourrait juste renvoyer la sortie de LSA! Pourquoi?

+0

Cela dépend. Les deux idiomes sont utilisés. Les deux ont des avantages et des inconvénients. –

+0

Quels sont alors les avantages du second cas, outre le fait d'être capable d'utiliser un tampon basé sur une pile? – wj32

+0

Il permet à l'appelant d'utiliser leur choix d'allocateur. Si vous allouez de la mémoire et laissez l'appelant libérer, l'appelant doit utiliser le deallocater correspondant - ce qui peut ne pas être leur préférence. Le remplissage d'un tampon fourni par l'appelant leur permet de choisir un allocateur approprié pour leurs besoins, plutôt que de se fier à celui choisi par l'API. –

Répondre

5

L'API Win32 ne pré-alloue pas de tampons car elle souhaite donner au code appelant le choix de la manière de fournir le tampon. Il leur permet de fournir une pile et une variété de tampons basés sur le tas. Il existe plusieurs endroits où la taille maximale du tampon est connue à l'avance et les développeurs veulent la simplicité d'utilisation d'un tampon basé sur une pile.

Le système de fichiers est le meilleur exemple car les chemins ne dépasseront pas MAX_PATH. Donc plutôt que d'allouer + gratuit. Le développeur déclare simplement un tampon basé sur une pile.

L'avantage de disposer de l'API C allouer de la mémoire est qu'elle simplifie le modèle d'appel. L'inconvénient du modèle Win32 est que la plupart du temps vous finissez par appeler l'API deux fois. La première fois pour déterminer la taille du tampon, puis la deuxième fois avec un tampon de taille appropriée. Avec un tampon alloué par l'API, un seul appel est nécessaire. L'inconvénient est que vous supprimez le choix de l'allocation de l'appelant. De plus, vous devez communiquer votre choix afin de libérer correctement l'API (par exemple, les fenêtres peuvent être allouées à partir de plusieurs endroits différents).

+3

Je noterais qu'il est si simple d'encapsuler les deux appels plus l'attribution dans votre propre fonction, que la simplification du modèle d'appel est une préoccupation très mineure. Si vous ne proposez qu'une version de l'API, celle-ci doit être la plus flexible. –

1

La deuxième approche présente certains avantages comme

  • Il permet aux appelants de gérer la durée de vie des allocations de mémoire
  • Il permet aux appelants de réutiliser la mémoire allouée aux différents appels qui suivent ce même modèle
  • Il permet aux appelants pour décider quel tampon pour fournir par exemple pile ou tas.