Sewer
Incluso los más grandes palacios necesitaban alcantarillas. Tom Lehrer
Funciones
void | (*FPtr_destroy (...)) |
type* | (*FPtr_copy (...)) |
void | (*FPtr_scopy (...)) |
int | (*FPtr_compare (...)) |
int | (*FPtr_compare_ex (...)) |
void | (*FPtr_assert (...)) |
void | unref (...) |
Tipos y Constantes
Sewer es la primera librería dentro del SDK de NAppGUI (Figura 1). En ella se declaran los tipos básicos, el soporte para Unicode, aserciones, manipulación segura de punteros, funciones matemáticas elementales, E/S estándar y reserva dinámica de memoria. También es utilizada como "sumidero" donde enterrar las antiestéticas macros del preprocesador necesarias para configurar el compilador, CPU, plataformas, etc. Depende tan solo de la librería estándar de C.
1. La librería estándar de C
La librería estándar de C (cstdlib) no forma parte núcleo del lenguaje C, pero implementa funciones de gran utilidad para el desarrollador que resuelven problemas típicos de programación. Cualquier programador de C las ha utilizado en mayor o menor medida y su estudio va normalmente ligado con el aprendizaje del propio lenguaje (Figura 2).
Esta librería se sitúa a medio camino entre la aplicación y las llamadas al sistema y proporciona un API portable para acceso a archivos, memoria dinámica, E/S, tiempo, etc (Figura 3). También implementa funciones matemáticas, de conversión, búsqueda, manejo de cadenas, etc. De una forma o de otra, NAppGUI integra toda su funcionalidad, por lo que no es necesario (ni recomendable) utilizar cstdlib directamente en la capa de aplicación. Las razones que han motivado esta decisión de diseño las podemos resumir en:
- Pequeñas diferencias: Los sistemas tipo-Unix no soportan las versiones seguras del cstdlib implementadas por Microsoft (
strcpy_s()
y otras). El uso de las funciones clásicas (sin el sufijo_s
) es inseguro y activarán molestos warnings en Visual Studio. - Seguridad: Relacionada con la anterior, evita vulnerabilidades del tipo buffer overflow en el tratamiento de cadenas y bloques de memoria.
- Duplicidad: Mucha de la funcionalidad de cstdlib ya se implementa en la librería osbs utilizando directamente llamadas al sistema (archivos, memoria dinámica, E/S, tiempo, etc).
- Completo: Las funciones de cstdlib relacionadas con archivos (
fopen()
y demás) no incorporan soporte para el manejo de directorios. Archivos y directorios presenta un API completo basado en llamadas al sistema. - Rendimiento: En ciertos casos, sobre todo en funciones matemáticas y gestión de memoria, puede ser interesante cambiar la implementación de cstdlib por otra mejorada. Todas las aplicaciones se beneficiarán del cambio, sin tener que modificar su código.
- Claridad: El comportamiento de algunas funciones del cstdlib no es del todo claro y puede llevar a confusión. Por ejemplo,
strtoul
tiene un funcionamiento muy particular que debemos recordar cada vez que la utilicemos. - Estilo: El uso de funciones sewer no rompe la estética de una aplicación escrita con NAppGUI.
- Independencia: NAppGUI utiliza internamente un subconjunto muy pequeño de funciones cstdlib. Es posible que en un futuro realicemos nuestras propias implementaciones y desvinculemos completamente el soporte de la librería estándar.
- Enlace estático: Si realizamos un enlace estático de la librería estándar, sewer contendrá todas las dependencias internamente. Esto evitará posibles incompatibilidades con los runtime instalados en cada máquina (los clásicos VC++ Redistributables de Windows). Con esto tendremos la certeza de que nuestros ejecutables van a funcionar, con independencia de la versión de runtime de C existente en cada caso. Si todas las llamadas a cstdlib están dentro de sewer, liberamos a las librerías de nivel superior de su gestión y de los posibles errores en tiempo de ejecución relacionados con el runtime de C.
1 2 3 4 5 6 7 |
1 2 3 4 5 6 7 |
real32_t a1 = 1.43f; real64_t a2 = .38; real32_t c = (real32_t)cosf((float)a1); real64_t t = (real64_t)tan((double)a2); ... real32_t c = bmath_cosf(a1); real64_t t = bmath_tand(a2); |
|
RUNTIME_C_LIBRARY "static" dumpbin /dependents dsewer.dll Image has the following dependencies: KERNEL32.dll |
|
RUNTIME_C_LIBRARY "dynamic" dumpbin /dependents dsewer.dll Image has the following dependencies: KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll |
Para evitar posibles errores o incompatibilidades, no utilices funciones de la Librería Estándar de C directamente en las aplicaciones. Busca siempre una función de NAppGUI equivalente.
int8_t
Entero con signo de 8 bits. Puede representar un valor entre INT8_MIN y INT8_MAX.
int16_t
Entero con signo de 16 bits. Puede representar un valor entre INT16_MIN y INT16_MAX.
int32_t
Entero con signo de 32 bits. Puede representar un valor entre INT32_MIN y INT32_MAX.
int64_t
Entero con signo de 64 bits. Puede representar un valor entre INT64_MIN y INT64_MAX.
uint8_t
Entero sin signo de 8 bits. Puede representar un valor entre 0 y UINT8_MAX.
uint16_t
Entero sin signo de 16 bits. Puede representar un valor entre 0 y UINT16_MAX.
uint32_t
Entero sin signo de 32 bits. Puede representar un valor entre 0 y UINT32_MAX.
uint64_t
Entero sin signo de 64 bits. Puede representar un valor entre 0 y UINT64_MAX.
char_t
Tipo carácter de 8 bits (Unicode). Un solo carácter puede necesitar 1, 2, 3 o 4 elementos (bytes), dependiendo de Codificaciones UTF.
byte_t
Tipo de 8 bits para almacenar bloques de memoria genéricos.
bool_t
Booleano de 8 bits. Solo dos valores son correctos TRUE (1) y FALSE (0).
real
Número de punto flotante de 32 o 64 bits.
real32_t
Número de punto flotante de 32 bits. El tipo float
de C.
real64_t
Número de punto flotante de 64 bits. El tipo double
de C.
TRUE
const bool_t TRUE = 1;
Cierto, verdadero.
FALSE
const bool_t FALSE = 0;
Falso.
NULL
const void* NULL = 0;
Puntero nulo.
INT8_MIN
const int8_t INT8_MIN = 0x80;
-128.
INT8_MAX
const int8_t INT8_MAX = 0x7F;
127.
INT16_MIN
const int16_t INT16_MIN = 0x8000;
-32.768.
INT16_MAX
const int16_t INT16_MAX = 0x7FFF;
32.767.
INT32_MIN
const int32_t INT32_MIN = 0x80000000;
-2.147.483.648.
INT32_MAX
const int32_t INT32_MAX = 0x7FFFFFFF;
2.147.483.647.
INT64_MIN
const int64_t INT64_MIN = 0x8000000000000000;
-9.223.372.036.854.775.808.
INT64_MAX
const int64_t INT64_MAX = 0x7FFFFFFFFFFFFFFF;
9.223.372.036.854.775.807.
UINT8_MAX
const uint8_t UINT8_MAX = 0xFF;
255.
UINT16_MAX
const uint16_t UINT16_MAX = 0xFFFF;
65.535.
UINT32_MAX
const uint32_t UINT32_MAX = 0xFFFFFFFF;
4.294.967.295.
UINT64_MAX
const uint64_t UINT64_MAX = 0xFFFFFFFFFFFFFFFF;
18.446.744.073.709.551.615.
enum unicode_t
Representa las Codificaciones UTF.
enum unicode_t
{
ekUTF8,
ekUTF16,
ekUTF32
};
ekUTF8 | Codificación UTF8. |
ekUTF16 | Codificación UTF16. |
ekUTF32 | Codificación UTF32. |
struct REnv
Entorno de Números aleatorios.
struct REnv;
FPtr_destroy
Prototipo de función destructora.
void (*FPtr_destroy)(type **item);
item | Doble puntero al objeto a destruir. Debe ser puesto a |
FPtr_copy
Prototipo de constructor de copia.
type* (*FPtr_copy)(const type *item);
item | Puntero al objeto que debe ser copiado. |
Retorna
El nuevo objeto que es una copia exacta de la entrada.
FPtr_scopy
Prototipo de constructor de copia sin asignar memoria.
void (*FPtr_scopy)(type *dest, const type *src);
dest | Objeto destino (copia). |
src | Puntero al objeto que debe ser copiado (source). |
Observaciones
En esta operación de copia, la memoria que necesita el objeto ya ha sido asignada. Debemos crear memoria dinámica para los campos del objeto que lo requieran, pero no para el objeto en sí mismo. Suele utilizarse para copiar arrays de objetos (no punteros a objetos).
FPtr_compare
Prototipo de función de comparación.
int (*FPtr_compare)(const type *item1, const type *item2);
item1 | Primer elemento a comparar. |
item2 | Segundo elemento a comparar. |
Retorna
Resultado de la comparación.
FPtr_compare_ex
Similar a FPtr_compare
, pero recibe un parámetro adicional que puede influir en la comparación.
int (*FPtr_compare_ex)(const type *item1, const type *item2, const dtype *data);
item1 | Primer elemento a comparar. |
item2 | Segundo elemento a comparar. |
data | Parámetro adicional. |
Retorna
Resultado de la comparación.
FPtr_assert
Prototipo de función callback llamada cuando se produce un assert
.
void (*FPtr_assert)(type *item, const uint32_t group, const char_t *caption, const char_t *detail, const char_t *file, const uint32_t line);
item | Datos de usuario pasados como primer parámetro. |
group | 0 = Error fatal, 1 = La ejecución puede continuar. |
caption | Título. |
detail | Mensaje detallado. |
file | Archivo fuente donde ocurrió el assert. |
line | Línea dentro del archivo fuente. |
unref ()
Marca el parámetro como no referenciado, desactivando los avisos del compilador.
void
unref(param);
param | Parámetro. |