DLLs Con Dev-C++
DLLs Con Dev-C++
DLLs Con Dev-C++
&$3,78/2,&UHDFLyQGHOD'//\GHODDSOLFDFLyQGHWHVW
El objetivo es crear una DLL utilizando Dev-C++. Para ello necesitamos tener instalado en
nuestro ordenador el programa Dev-C++, programa que te puedes bajar libremente de:
http://www.bloodshed.net/devcpp.html
Una vez que lo tenemos instalado, vamos a crear la DLL. Lo que vamos a conseguir es una
DLL programada en C++, ms una aplicacin de test que utiliza las funciones de la DLL.
Para ello, vamos a realizar los siguientes pasos. Hay que tener en cuenta que puede que las
ventanas tengan otro aspecto, dependiendo de la versin de Dev-C++ utilizada.
1. Opcin del men "File -> New Project..."
2. Tipo "DLL" y lenguaje "C++". Pulsar OK
- DLL Project filename: Pulsar el boton con los 3 ptos y seleccionar un nombre (se puede
definir un nombre nuevo)
- Main source filename: Dejar el que sale por defecto (MainDll)
3.2. Opciones DLL Test Project: este proyecto va a crear la aplicacion que usa la DLL
- DLL Project name: MyTestDLL
- DLL Project filename: Pulsar el boton con los 3 ptos y seleccionar un nombre (se puede
definir un nombre nuevo)
- Main source filename: Dejar el que sale por defecto (MainExe)
3.3 Pulsar OK. Nos sale un mensaje que dice que va a abrir el projecto DLL y que luego
debemos usar la DLL con el programa de test. Le damos a OK
4. Ya tenemos la DLL. Le damos a compilar y nos genera la DLL
5. Ahora, para ver si funciona correctamente, cerramos el proyecto de la DLL y abrimos el
proyecto que la usa, el cual hemos creado en el punto 3.2.
6. Compilamos el proyecto abierto en el punto 5. y lo ejecutamos y "tachachn!" llama a las
funciones de la DLL
&$3,78/2,,3HUR4XpHVXQD'//"4XpHVORTXHJHQHUR"
Vamos a mirar dentro de la DLL, para ver qu es lo que tenemos y comprender cmo
funciona, pero primero, una explicacin previa: existen dos formas de integrar una DLL en
nuestro programa:
- A travs de la informacin que la propia DLL contiene, sin ningn archivo externo y
basndonos solo en la documentacin de la DLL. Este mtodo NO es el que usaremos (de
momento)
- O a travs del archivo de cabecera (*.h) y la librera esttica (*.lib) que la DLL genera al
compilarse. Este mtodo es el que usaremos.
Vamos a abrir el proyecto de la DLL y a hacer un par de cambios en l, para aclarar su
funcionamiento. Abrimos, pues, el proyecto MyDLL y vemos que tenemos 2 archivos,
MainDLL.cpp y MainDLL.h. Nos fijamos primero en el archivo de cabecera.
Abrimos el archivo MainDll.h y al principio, vemos lo siguiente:
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */
Ufff! Parece complicado, pero no hay que desanimarse, slo son macros!
Vemos que se distingue enrtre estar FUHDQGR la DLL (BUILDING_DLL) o estar XWLOL]DQGR la
DLL. Hay que darse cuenta que:
- al FUHDU la DLL se define la macro DLLIMPORT como GOOH[SRUW
- mientras que al XWLOL]DU la DLL, se define DLLIMPORT como GOOLPSRUW
Es decir, al crear la DLL, vamos a exportar el cdigo/programa que hagamos a otros
programas, mientras que al utilizar la DLL, lo que hacemos es importar ese programa
anteriormente creado.
El resto del archivo de cabecera es la implementacin de una clase que realiza algo; en este
ejemplo, la DLL solo muestra un mensaje. Un punto importante es que en las declaraciones
tenemos lo siguiente:
struct DLLIMPORT
DllClassBase {
virtual int virtual_method () const;
};
Como se ve, ah se utiliza la macro DLLIMPORT, de tal manera que cuando utilicemos la
DLL, estaremos importando el cdigo que se haya creado en la DLL a nuestro programa,
mientras que cuando estemos programando la DLL en s, estaremos exportando el cdigo.
As, por medio de una simple macro, el mismo archivo de cabecera sirve para crear Y para
utilizar la DLL.
Ahora, vamos a detenernos en el archivo MainDll.cpp. Lo abrimos y lo primero que
vemos es que en este archivo est includo MainDLL.h. Esto es obvio, pues necesitamos
para compilar la definicin de las funciones y clases que vamos a necesitar. Ahora,
compilamos el proyecto para empezar a ver cosas. Todo tiene que ir con normalidad, sin
errores, pero an as pulsamos en la pestaa de Compile Log , vemos lo siguiente:
Osea, el archivo de cabecera se usar para exportar la DLL (vamos, para crearla).
Otro punto importante que vemos es que el linker nos muestra un warning :
Qu significa esto?
Eso significa que la DLL define nombres para las funciones de forma interna, y que esos
nombres son convertidos en un formato legible de forma automtica; para ver lo que ha
hecho, podemos abrir el archivo dll.def que se nos ha generado. De momento, esto no nos
interesa.
Lo que s nos interesa es el archivo LIB que antes he nombrado de pasada. Dicho archivo
contiene la implementacin en s de las funciones, y lo necesitaremos en nuestro programa de
test despus. Si abrimos de nuevo la ventana del Compile log y desplazamos un poco la
barra a la derecha vemos lo siguiente:
Eso quiere decir que hemos generado un archivo LIB con el nombre libTemp-dll.a
Ahora abrimos el archivo MainDll.cpp, que contiene el resto del cdigo de la DLL. En el
archivo est includo MainDll.h (ya lo esperbamos) y contiene la implementacin de las
clases DllClassBase y DllClass. Pero antes de ese cdigo, tenemos lo siguiente:
/* Externs */
DllClass DLLIMPORT global_dllclass1 (1);
DllClass DLLIMPORT global_dllclass2 (2);
int DLLIMPORT global_int_variable = 5;
Estas son variables globales que la DLL crea y exporta para que otras aplicaciones las puedan
usar. Recordar que DLLIMPORT, cuando estamos generando la DLL, est definida como
H[SRUW. Que no os confundan los nombres!1
Posteriormente, en el cdigo, tenemos la implementacin de los datos y funciones de las
clases, y al final, se llega a la parte interesante: la funcin DllMain. Tenemos la definicin
de la funcin y su implementacin. Esta funcin es para la DLL lo que la funcin main para
los programas, es decir, su punto de entrada. Cuando una aplicacin carga la DLL, lo primero
que hace Windows es llamar a esta funcin. Como veis, en realidad slo se trata de un switch
en el cual se definen ciertas funcionalidades, dependiendo del modo en que se
inicialice/finalice la DLL. En la prctica, nada de esto se utiliza muy a menudo, sino otros
mtodos que iremos viendo.
Como resumen, en realidad al generar la DLL se utilizan otros 2 archivos que son los
necesarios para compilar aplicaciones que usen la DLL:
- Al compilar, necesitamos el archivo de cabecera y el LIB
- Al ejecutar, necesitamos la DLL en s
Es igual que el nombre mano . A la pregunta, Cuntas manos tienes? La respuesta intuitiva es 2, pero desde el
punto de vista de software, eso es problemtico: tenemos una mano derecha y una mano izquierda, que
casualmente se llaman igual (mano) pero que no son lo mismo
&$3,78/2,,,&yPRXVDQRWURVSURJUDPDVOD'//
Para este Captulo, necesitamos el proyecto MyTestDLL, descrito en los puntos 5 y 6 del
Captulo I. Una vez abierto, vemos que dicho proyecto consta de un nico archivo:
MainExe.cpp, pero dentro de el archivo, tenemos la siguiente lnea de cdigo (el contenido
exacto puede variar):
#include "C:\Programme\Dev-C++\Proyectos\Temp\MainDll.h"
Es el archivo de cabecera del proyecto MyDLL, es decir de la DLL en s. Para verlo con ms
detalle, incluimos este archivo en nuestro proyecto: Elegimos la opcin de men Project
- Add to project... y seleccionamos el archivo que ponga en el include. Abrimos
dicho archivo MainDll.h y tenemos las conocidas lneas:
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */
Ahora, estamos XWLOL]DQGR la DLL, no creando, con lo que la macro DLLIMPORT est
definida como GOOLPSRUW,es decir, vamos a es importar este programa la DLL. Pero antes, al
definir en el Captulo II la DLL, hemos visto que adems, existe un archivo LIB. Pero, dnde
est?
Para ver dnde est este archivo, tenemos que abrir la opcin de men Project Project
options..., en el cual vemos: