lomo2.cpp
, cuya adecuada compilación producirá
el ejecutable lomo2.exe
. Por favor, mantened los
nombres tal cual, incluida la extensión. Se trata de realizar
una práctica casi idéntica a la segunda
práctica de este año, pero
mediante un programa que realice llamadas a la API de WIN32.
liblomo.a
. La biblioteca se llamará
lomo2.dll
.
lomo2.h
. Las funciones proporcionadas por la
DLL que devuelven un entero, devuelven -1 en caso de error. A
continuación se ofrecen los prototipos de todas las funciones
incluidas en la DLL:
int LOMO_inicio(int ret)
liblomo.a
, pero
con un par de parámetros menos.
int LOMO_trenNuevo(void)
int LOMO_peticiOnAvance(int nt, int *xcab,
int *ycab)
int LOMO_avance(int nt, int *xcola,
int *ycola)
char *LOMO_getColor(int nt)
void LOMO_espera(int y, int yn)
liblomo.a
int LOMO_fin(void)
void pon_error(char *mensaje)
pon_error
el texto
"INTERBLOQUEO
". Opcionalmente, y para optar a
más puntuación, la práctica podrá añadir al mensaje los colores
de los trenes que participan en el interbloqueo.
En el caso de que se hayan producido más de un interbloqueo
simultáneo, basta con que se identifique uno cualquiera de
ellos.
lomo2.dll
lomo2.dll
y el fichero de cabeceras lomo2.h
.
lomo2.dll
ver. 1.2:
Descárgalo de aquí.
lomo2.h
ver. 1.1:
Descárgalo de aquí.
EVENTOS Y VALOR INICIAL: EC* (automático), EV (automático). SEUDOCÓDIGO: C V === === Por_siempre_jamás Por _siempre_jamás { { W(EC) W(EV) escribir_consonante escribir_vocal Set(EV) Set(EC) } }Debéis indicar, asimismo, en el caso de que las hayáis programado, las optimizaciones de código realizadas.
TerminateThread
para acabar con
los hilos o TerminateProcess
para acabar con
los procesos. El problema de estas funciones es que
están diseñada para ser usada sólo en condiciones
excepcionales y los hilos mueren abruptamente.
Puede dejar estructuras colgando, ir llenando
la memoria virtual del proceso con basura o no
invocar adecuadamente las funciones de descarga de la
DLL.
fprintf(stderr,...)
a
un fichero, añadiendo al final de la línea de órdenes
2>salida
. De este modo, toda la información
aparecerá en el fichero salida
para su
análisis posterior. No os olvidéis de incluir el
identificador del hilo que escribe el mensaje.
XXXX
de la biblioteca. No consigo de
ningún modo acceder a ella.XXXX
por lo que veremos más
abajo. Para definir el tipo de esta variable
correctamente, debéis conocer cómo son los
punteros a función. En la
sesión quinta,
se describe una función, atexit
.
Dicha función en sí no es importante para lo
que nos traemos entre manos, pero sí el argumento
que tiene. Ese argumento es un puntero a función.
Fijándoos en ese argumento, no os resultará
difícil generalizarlo para poner un puntero
a funciones que admiten otro tipo de parámetros
y devuelve otra cosa.
Notad, además, que, al contrario que
ocurre con las variables "normales", la definición
de una variable puntero a función es especial
por cuanto su definición no va sólo antes del
nombre de la variable, sino que lo rodea.
Tenéis que poner algo similar a:
#$%&%$ XXXX $%&$·@;
, es decir,
algo por delante y algo por detrás.
GetProcAddress
.
Pero, ¡cuidado!, GetProcAddress
devuelve un FARPROC
, que sólo
funciona con punteros a funciones que devuelven
int
y no se les pasa nada
(void)
. Debéis hacer el
correspondiente casting. Para ello,
de la definición de vuestro puntero, quitáis
el nombre, lo ponéis todo entre paréntesis
y lo añadís delante de
GetProcAddress
, como siempre.
XXXX
como nombre al puntero,
ahora no se diferenciarán en nada vuestras
llamadas a la función respecto a si dicha
función no perteneciera a una DLL y la
hubierais programado vosotros.
.h
si llamáis a vuestro
fichero fuente con extensión .c
. Llamadlo
siempre con extensión .cpp
.
libc
(malloc
y free
). Son funciones que no están
sincronizadas, es decir, no se comportan bien
en entornos multihilo. O bien las metéis en una
sección crítica o, mejor aún, tratad de evitarlas.