Llamadas a funciones estáticas externas en C

Sí, sí, ya lo sé. ¿Por qué querría alguien hacer una llamada a una función declarada como estática desde otro módulo?

Si una función se ha declarado estática para restringir el acceso a la misma, para no incluirla en el API del módulo, ¿por qué “bypassear” la funcionalidad y acceder a ella?

En mi caso, la respuesta es sencilla: pruebas unitarias. ¿Cómo hacer pruebas unitarias de estas rutinas?

La respuesta es, creando punteros a estas rutinas, accesibles desde otros módulos. Y puesto que cualquier solución implica cambios en los módulos a probar, en el ejemplo a continuación trataré de ser lo menos “intrusivo” posible.

Supongamos el módulo stfunc.c:

#include <stdio.h>
static int funcprintf(const char* str) {
   return printf(str);
}

Para probar esta rutina, tenemos esta otra, en otro fichero diferente (main.c):

int main() {
   int a = funcprintf("Loquesea");
   return a;
}

Si intentamos compilar, obtenemos el error “undefined reference to `funcprintf’”.

Así pues, vamos a crear un puntero a esta rutina para permitir el acceso a la misma desde el módulo de prueba. Creamos un fichero llamado ptrdefs.h:

#ifndef _PTRDEFS_H
#define _PTRDEFS_H
int (*fpointer)(const char*) = &funcprintf;
#endif

Y modificamos los ficheros anteriores de esta manera:
Fichero stfunc.c:

#include <stdio.h>

static int funcprintf(const char* str) {
   return printf(str);
}

#ifdef UNIT_TESTING
#include
<ptrdefs.h>
#endif

Fichero main.c:

int main() {
   int a = fpointer("Loquesea");

   return a;
}

Con esto, basta añadir la opción -DUNIT_TESTING para tener acceso a la rutina.

Por tro lado, el fichero ptrdefs.h sólo estará disponible para los tests unitarios. Esto evita el acceso indeseado.

[Código completo del ejemplo: static.tgz]

Compartir:
  • Facebook
  • Twitter
  • Google Bookmarks
  • BarraPunto
  • DZone
  • Meneame

Relacionados:

  1. GNUmakefile para Objective-C y Objective-C++
  2. Expresiones regulares C
  3. Utilización de gprof/gcov para obtención de datos de cobertura (I)
  4. Utilización de gprof/gcov: cobertura de ramas (y II)
  5. AspectJ aplicado sobre una librería jar

Tags: , , ,

Leave a Reply

Get Adobe Flash playerPlugin by wpburn.com wordpress themes