¿Existe algún estándar relacionado con la forma en que se debe implementar una biblioteca c o tiene que volver a aprender la peculiaridad de las implementaciones de una biblioteca cuando se cambia a una nueva placa que proporciona un BSP diferente?
En primer lugar, el estándar de C define algo que se llama una implementación "independiente", a diferencia de una implementación "alojada" (que es con lo que la mayoría de nosotros estamos familiarizados, la gama completa de funciones de C admitidas por el sistema operativo subyacente).
Una implementación "independiente" necesita definir solo un subconjunto de los encabezados de la biblioteca C, es decir, aquellos que no requieren soporte, o incluso la definición de funciones (simplemente hacen #define
sy typedef
s):
-
<float.h>
-
<iso646.h>
-
<limits.h>
-
<stdalign.h>
-
<stdarg.h>
-
<stdbool.h>
-
<stddef.h>
-
<stdint.h>
-
<stdnoreturn.h>
Cuando esté dando el siguiente paso hacia una implementación hospedada, encontrará que solo hay muy pocas funciones que realmente necesiten una interfaz con "el sistema" de cualquier manera, con el resto de la biblioteca implementable por encima de esos "primitivos". Al implementar el PDCLib , hice un esfuerzo para aislarlos en un subdirectorio separado para una identificación fácil al transferir la biblioteca a una nueva plataforma (ejemplos para el puerto de Linux entre paréntesis):
-
getenv()
( extern char * * environ
)
-
system()
( fork()
/ execve()
/ wait()
)
-
malloc()
y free()
( brk()
/ sbrk()
)
-
_Exit()
( _exit()
)
-
time()
(no implementado todavía)
Y para <stdio.h>
(posiblemente el más "involucrado con el sistema operativo" de los encabezados C99):
- alguna forma de abrir un archivo (
open()
)
- alguna forma de cerrarla (
close()
)
- alguna forma de eliminarlo (
unlink()
)
- alguna forma de cambiarle el nombre (
link()
/ unlink()
)
- alguna forma de escribirle (
write()
)
- alguna forma de leerlo (
read()
)
- alguna forma de reposicionar dentro de él (
lseek()
)
Ciertos detalles de la biblioteca son opcionales, ya que el estándar simplemente los ofrece para que se implementen de manera estándar, pero no hace que tal implementación sea un requisito.
-
La función time()
puede devolver legalmente (time_t)-1
si no hay mecanismos de cronometraje disponibles.
-
Los manejadores de señales descritos para <signal.h>
no deben ser invocados por otra cosa que no sea una llamada a raise()
, no hay ningún requisito de que el sistema envíe algo así como SIGSEGV
a la aplicación.
-
El encabezado C11 <threads.h>
, que es (por razones obvias) muy dependiente del sistema operativo, no se debe proporcionar en absoluto si la implementación define __STDC_NO_THREADS__
...
Hay más ejemplos, pero no los tengo a mano en este momento.
El resto de la biblioteca se puede implementar sin ayuda del entorno. (*)
(*) Advertencia: la implementación de PDCLib aún no está completa, así que podría haber pasado por alto una o dos cosas. ;-)