J'ai du mal à trouver des conseils pragmatiques du monde réel sur les conventions de dénomination des fonctions pour un projet de bibliothèque C de taille moyenne. Mon projet de bibliothèque est séparé en quelques modules et sous-modules avec leurs propres en-têtes, et suit vaguement un style OO (toutes les fonctions prennent une certaine structure comme premier argument, pas de globaux, etc.). Il a posé notre quelque chose comme:
MyLib
- Foo
- foo.h
- foo_internal.h
- some_foo_action.c
- another_foo_action.c
- Baz
- baz.h
- some_baz_action.c
- Bar
- bar.h
- bar_internal.h
- some_bar_action.c
Généralement, les fonctions sont beaucoup trop volumineuses pour (par exemple) rester some_foo_action
et another_foo_action
dans un foo.c
fichier d'implémentation, rendre la plupart des fonctions statiques et l'appeler un jour.
Je peux gérer le retrait de mes symboles internes ("module privé") lors de la construction de la bibliothèque pour éviter les conflits pour mes utilisateurs avec leurs programmes clients, mais la question est de savoir comment nommer les symboles dans ma bibliothèque? Jusqu'à présent, je fais:
struct MyLibFoo;
void MyLibFooSomeAction(MyLibFoo *foo, ...);
struct MyLibBar;
void MyLibBarAnAction(MyLibBar *bar, ...);
// Submodule
struct MyLibFooBaz;
void MyLibFooBazAnotherAction(MyLibFooBaz *baz, ...);
Mais je me retrouve avec des noms de symboles longs et fous (beaucoup plus longs que les exemples). Si je ne préfixe pas les noms avec un "faux espace de noms", les symboles internes des modules sont tous en conflit.
Remarque: je ne me soucie pas du cas camelcase / Pascal, etc., juste des noms eux-mêmes.
la source
git merge
ing. À titre d'exemple, j'ai un module pour dessiner l'interface utilisateur avec OpenGL, et j'ai des.c
fichiers séparés pour chaque élément dont j'ai besoin (slider.c
,indicator.c
etc.). Ces implémentations d'éléments ont une fonction de dessin principale de quelques centaines de lignes et un bon nombre d'static
aides. Ils appellent également quelques fonctions de géométrie pure à partir du module d'interface utilisateur. Cela vous semble-t-il assez typique?Audio Module > Engines > Channels > Filters
ce qui signifie quelque chose commeMyLibAudioEngines<EngineName>Channel<ActionName>
. Ou dans mon sous-module de filtres:MyLibAudioFilters<FilterName><Type><Action>
par exemple.MyLibAudioFiltersBigSoundingCompressorFloat32Process
La convention habituelle pour les bibliothèques C est d'utiliser le nom de la bibliothèque comme préfixe pour les noms utilisables en externe, par exemple
Pour les noms internes à la bibliothèque qui doivent toujours être accessibles dans plusieurs unités de la bibliothèque, il n'y a pas de convention stricte, mais j'utiliserais un préfixe du nom de la bibliothèque et une indication qu'il s'agit d'une fonction interne. Par exemple:
Je suis d'accord que cela peut conduire à des noms assez longs et difficiles à taper, mais malheureusement c'est le prix à payer pour ne pas avoir de mécanisme comme les espaces de noms C ++. Pour réduire la longueur des noms, au prix d'une certaine clarté, vous pouvez choisir d'utiliser des abréviations dans vos noms, mais vous devez peser soigneusement les avantages et les inconvénients.
la source
Si vous voulez éviter les longs préfixes, vous pouvez abréger les noms de bibliothèques comme ce que fait Apple dans iOS et OS X:
la source
Qu'en est-il d'avoir une variable de structure globale préremplie de pointeurs de fonction?
lib.h
lib.c:
Harnais:
Le mot-clé statique limite la portée à l'unité de traduction afin qu'elle n'entre pas en collision avec d'autres.
L'utilisateur peut ensuite le raccourcir en utilisant un pointeur comme
YourApi *ya = &yourApi
, puis en utilisantya->doFoo(...)
.Il fournit également un bon moyen de simuler votre bibliothèque pour les tests.
la source