Cool C/C++

Programacion en C/C++

Home Tutoriales Programación C/C++ Creación y uso de una librería dinámica (.dll)
Creación y uso de una librería dinámica (.dll) PDF Imprimir E-mail
Escrito por adrianvaca   
Domingo, 20 de Marzo de 2011 19:06

En esta ocasión vamos a ver como crear una dll sencilla y luego como podemos usarla en un programa de ejemplo.

Vamos a usar el compilador Dev-C++ 4.9.9.2, si no lo tienes descárgalo primero de la sección Compiladores de este sitio.

Empecemos, como siempre paso a paso:

Creación de la dll

  1. Primero que nada crearemos una carpeta de nombre utilidades en C:\Dev-Cpp\bin en la cual iremos guardando todos los archivos del proyecto. Abrimos el Dev-C++ y vamos a Archivo -> Nuevo -> Proyecto, seleccionamos DLL y el nombre del proyecto será utilidades tal como se muestra:



  2. Guardamos todos los ficheros en la carpeta creada anteriormente y dejamos los nombres por defecto para los ficheros, vemos que se han creado los ficheros: dllmain.cpp y dll.h como se muestra:



  3. Ahora cambiamos el código del fichero dll.h por el siguiente:

    /* dll.h */

    #ifndef _DLL_H_
    #define _DLL_H_

    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */



    #endif /* _DLL_H_ */


    Este es un código que por lo general hay que dejarlo así


  4. Ahora cambiamos el código del fichero dllmain.cpp por el siguiente:

    /* dllmain.cpp */

    #include "dll.h"
    #include <windows.h>

    extern "C" _declspec(dllexport)
    int suma(int a, int b)
    {
        return a + b;
    }

    int longitud(char *cadena)
    {
        int len = 0;
        for(int i=0; ; i++)
        {
            if(cadena[ i ] == '\0')
               break;
               
            len ++;
        }
        return len;
    }

    extern "C" _declspec(dllexport)
    int es_palindroma(char *cadena)
    {
       int i;
       char invertida[50];

       /* Halla la cadena invertida */
       for(i=0; i < longitud(cadena); i++)
           invertida[ i ] = cadena[longitud(cadena)-i-1];

       /* Coloca caracter de fin de cadena */
       invertida[ i ] = '\0';

       /* Realiza la comparacion */
       if(!strcmp(cadena, invertida))
          return 1; /* es un palindromo */
             
       return 0;  /* no es un palindromo */
    }


    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                           DWORD reason        /* Reason this function is being called. */ ,
                           LPVOID reserved     /* Not used. */ )
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
            break;

          case DLL_PROCESS_DETACH:
            break;

          case DLL_THREAD_ATTACH:
            break;

          case DLL_THREAD_DETACH:
            break;
        }

        /* Returns TRUE on success, FALSE on failure */
        return TRUE;
    }


    Como podemos mirar, las funciones suma y es_palindroma están precedidas por la siguiente línea de código:

    extern "C" _declspec(dllexport)


    Mediante esta línea decimos que las funciones definidas a continuación serán públicas, es decir que pueden ser usadas por cualquier que tenga la dll resultante. La función longitud es privada, es decir que sólo puede ser usada al interior de la dll, se trata de una función de utilería.


  5. Bien, ahora vamos a compilar, para ello, simplemete presionamos CTRL+F9 y podemos ver el resultado de la compilación:



  6. Bien con esto ya hemos creado nuestra dll. Si vamos al Explorador de Windows a nuestra carpeta de trabajo, podemos ver que se han creado algunos ficheros, de todos estos, la dll es obviamente : utilidades.dll, los demás ficheros tienen el fuente de la dll. Si queremos distribuír nuestra dll sólo hace falta entregar este fichero y ningún otro más.


Uso de la dll

  1. Ahora que tenemos la librería o dll resultante, vamos a crear un programa de prueba. Primero que nada crearemos una carpeta de nombre testUtilidades en C:\Dev-Cpp\bin en la cual iremos guardando todos los archivos de este proyecto de prueba. Copiamos el archivo utilidades.dll en la carpeta testUtilidades. Abrimos el Dev-C++ y vamos a Archivo -> Nuevo -> Proyecto, seleccionamos Console Application y el nombre del proyecto será testUtilidades tal como se muestra:



    Reemplazamos el código inicial por el siguiente:

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>

    using namespace std;

    int suma_int(int, int);
    int es_cadena_palindroma(char *);

    typedef int (WINAPI*cfunc1)(int, int);
    cfunc1 ConexionDLL1;

    typedef int (WINAPI*cfunc2)(char *);
    cfunc2 ConexionDLL2;

    int main(int argc, char *argv[])
    {
        int a, b, resultado;
        char cadena[50];
        cout << "Ingrese a: ";
        cin >> a;
        cout << "Ingrese b: ";
        cin >> b;
        resultado = suma_int(a, b);
        cout << "Resultado a+b=" << resultado;   
       
        cout << "\nIngrese cadena: ";
        cin >> cadena;
        if(es_cadena_palindroma(cadena))
           cout << "Es palindroma\n";
        else
           cout << "NO es palindroma\n";
       
        system("PAUSE");
        return EXIT_SUCCESS;
    }


    /*----------------------------*/
    /*         llamada dll        */
    /*----------------------------*/
    int suma_int(int a, int b)
    {         
         int res = 0;   
         HINSTANCE hLib;       
         hLib = LoadLibrary("utilidades.dll");
     
         if(hLib!=0)
         {
              ConexionDLL1 = (int (__stdcall *) (int, int)) GetProcAddress(hLib,"suma");
              res = ConexionDLL1(a, b);                                       
         }
         else
         {
             cout << "No se ha podido cargar DLL";
             FreeLibrary(hLib);
         }   
         
         return res;           
    }


    int es_cadena_palindroma(char *cadena)
    {         
         int res = 0;   
         HINSTANCE hLib2;       
         hLib2 = LoadLibrary("utilidades.dll");
     
         if(hLib2!=0)
         {
              ConexionDLL2 = (int (__stdcall *) (char *)) GetProcAddress(hLib2,"es_palindroma");
              res = ConexionDLL2(cadena);                                       
         }
         else
         {
             cout << "No se ha podido cargar DLL";
             FreeLibrary(hLib2);
         }   
         
         return res;           
    }


    En este punto hay que asegurarse primero de guardar todos los archivos. Podemos ver que usamos las 2 funciones públicas que creamos, si tratamos de usar la función longitud nos dará un error.

    Un poco de explicación:

    • En primer lugar colocamos:

      int suma_int(int, int);


      Este es el prototipo de la función definida más abajo, dentro de esta función instanciaremos la dll y llamaremos a la función suma definida en la misma dll. Nada nuevo por ahora.


    • Con el siguiente código definimos un prototipo de la función en la dll, definimos un alias, y creamos una variable que nos permitirá conectarnos a la dll:

      typedef int (WINAPI*cfunc1)(int, int);
      cfunc1 ConexionDLL1;


    • Dentro de la función suma_int cargamos la dll en memoria mediante la línea:

      hLib = LoadLibrary("utilidades.dll");


      Hay que asegurarse que se ha cargado la dll adecuadamente, para esto nos aseguramos que el valor devuelto sea distinto a 0.


    • Mediante la línea siguiente:

      ConexionDLL1 = (int (__stdcall *) (int, int)) GetProcAddress(hLib,"suma");


      Obtenemos una referencia a la función suma de la dll que fué previamente cargada en memoria.


    • Por último, llamamos a la función definida en la dll mediante:

      res = ConexionDLL1(a, b);


  2. Ahora compilamos el programa, para esto presionamos CTRL+F9 y el resultado de la compilación es:



  3. Ahora ejecutamos el programa, para esto presionamos CTRL+F10 y el resultado es:







Si, puede parecer complicado al inicio, esto de las dll, pero vamos con un poco de esfuerzo se puede comprender muy bien, revísen bien el código y lean completamente el artículo y listo!!


 
Otros artículos

Comentarios  

 
0 #2 Braulio 03-06-2013 13:24
Buenas. Estoy investigando sobre la creacion de una dll. Principalmente necesito hacer una dll para puerto serial, pero estoy tomando como referencia la que realizaste vos.
Me aparece un error al compilar dll.h. Me dice:
" C:\Documents and Settings\pc-Puertos\Mis documentos\DLL\ Makefile.win [Build Error] No rule to make target `dll.o'. Stop. ".
Sabes a que se refiere???
Citar
 
 
0 #1 Rafael 05-01-2012 08:12
muy bueno, gracias por el aporte alos que estamos iniciando nos sirve de mucho
Citar
 

Escribir un comentario


Código de seguridad
Refescar