Estoy luchando por encontrar consejos pragmáticos del mundo real sobre convenciones de nombres de funciones para un proyecto de biblioteca C de tamaño mediano. El proyecto de mi biblioteca está separado en unos pocos módulos y submódulos con sus propios encabezados, y sigue libremente un estilo OO (todas las funciones toman una cierta estructura como primer argumento, no globales, etc.). Se ha puesto algo así como:
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
En general, las funciones son demasiado grandes para (por ejemplo) pegarse some_foo_action
y another_foo_action
en un foo.c
archivo de implementación, hacer que la mayoría de las funciones sean estáticas y llamarlo un día.
Puedo tratar de quitar mis símbolos internos ("módulo privado") cuando construyo la biblioteca para evitar conflictos para mis usuarios con sus programas cliente, pero la pregunta es cómo nombrar símbolos en mi biblioteca. Hasta ahora he estado haciendo:
struct MyLibFoo;
void MyLibFooSomeAction(MyLibFoo *foo, ...);
struct MyLibBar;
void MyLibBarAnAction(MyLibBar *bar, ...);
// Submodule
struct MyLibFooBaz;
void MyLibFooBazAnotherAction(MyLibFooBaz *baz, ...);
Pero estoy terminando con nombres de símbolos largos y locos (mucho más largos que los ejemplos). Si no prefijo los nombres con un "espacio de nombres falso", los nombres de los símbolos internos de los módulos chocan.
Nota: No me importa el caso Camelcase / Pascal, etc., solo los nombres en sí.
fuente
git merge
rendimiento. Como ejemplo, tengo un módulo para dibujar la interfaz de usuario con OpenGL, y tengo.c
archivos separados para cada elemento que necesito (slider.c
,indicator.c
etc.). Estas implementaciones de elementos tienen una función de dibujo principal de unos cientos de líneas de largo y una buena cantidad destatic
ayudantes. También llaman a algunas funciones de geometría pura desde el módulo UI. ¿Suena bastante típico?Audio Module > Engines > Channels > Filters
que significa algo asíMyLibAudioEngines<EngineName>Channel<ActionName>
. O en mi submódulo de filtros:MyLibAudioFilters<FilterName><Type><Action>
por ejemplo.MyLibAudioFiltersBigSoundingCompressorFloat32Process
La convención habitual para las bibliotecas C es usar el nombre de la biblioteca como prefijo para los nombres que se pueden usar externamente, p. Ej.
Para los nombres internos de la biblioteca que aún deben estar accesibles en varias unidades de la biblioteca, no existe una convención estricta, pero usaría un prefijo del nombre de la biblioteca y una indicación de que es una función interna. Por ejemplo:
Estoy de acuerdo en que esto puede conducir a nombres que son bastante largos y difíciles de escribir, pero desafortunadamente ese es el precio que tenemos que pagar por no tener un mecanismo como los espacios de nombres C ++. Para reducir la longitud de los nombres, a costa de cierta claridad, puede optar por usar abreviaturas en sus nombres, pero debe sopesar cuidadosamente las ventajas y desventajas.
fuente
Si desea evitar los prefijos largos, puede abreviar los nombres de las bibliotecas como lo que Apple hace en iOS y OS X:
fuente
¿Qué pasa con tener una variable de estructura global precargada con punteros de función?
lib.h
lib.c:
Aprovechar:
La palabra clave estática limita el alcance a la unidad de traducción para que no choque con otros.
El usuario puede acortarlo usando un puntero como
YourApi *ya = &yourApi
, luego usandoya->doFoo(...)
.También proporciona una buena manera de burlarse de su biblioteca para realizar pruebas.
fuente