Crear dll con DevC++

Hola, no se ustedes… pero yo siempre me pregunte como rayos se crean esas cosas llamadas dll ( dynamic-link library | biblioteca de enlace dinámico ) y mas cuando en tiempos aquellos de Windows 98 llegaba a faltar alguna para ejecutar un programa.

Bien, empecemos definiendo que es en si un archivo dll. A groso modo un archivo dll viene siendo un archivo donde se encuentran almacenadas funciones que pueden llegar a ser llamadas por uno o varios programas.

Por ejemplo (recalco que es un ejemplo ficticio) :

El archivo msnmsgr.exe hace uso de sus bibliotecas [msgsres.dll, rtmpltfm.dll, psmsong.dll] exclusivas  para su funcionamiento, al igual que iexplorer.exe hace uso exclusivo de las suyas [jsdbgui.dll, , IEShims.dll, jsdebuggeride.dll] , pero los dos programas comparten la librería iexproxy.dll.

 

image

Los archivos dll además de ser compartidos por distintas aplicaciones, tienen la característica de que  pueden ser llamados en runtime (en ejecución).

Que ventajas nos trae que los programas compartan bibliotecas (*.dll) , la ventaja principal es el reducir el tamaño del programa ejecutable ( *.exe), pero al igual que existen ventajas, existen desventajas; la mas común y  odiada por todos es que un programa que desinstalamos desinstale una dll que era necesaria para otro programa.

Después de esta introducción, hablemos sobre el por que crear dll para nuestros programas. Siempre será mucho mas sencillo gestionar nuestra aplicación por módulos, donde se encuentren distintas funciones y sean fácilmente localizables, muy al estilo de las bibliotecas estáticas (*.h) a diferencia de las bibliotecas estáticas que se encuentran embebidas en el archivo exe, las bibliotecas de enlace dinámico (*.dll)  se encuentran, como archivos independiente reduciendo considerablemente el tamaño de nuestro archivo ejecutable, facilitando la actualización del mismo o bien de alguno de sus componentes.

Basta de hacerla de emoción, empecemos a escribir código.

1.- Abrimos DevC++ (mi versión es 4.9.9.2), Archivo –> Nuevo –> Proyecto

image

Elegimos “DLL”, de nombre colocamos “dll” y en tipo colocamos “En C”

 image

Guardamos nuestro proyecto como dll.dev

image

2.- Se abran creado 2 archivos automáticamente [ dllmain.c y dll.h ]

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 */


DLLIMPORT void HelloWorld (void);


#endif /* _DLL_H_ */

dllMain.c

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

DLLIMPORT void HelloWorld ()
{
    MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
}


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;
}

3.-En realidad con eso tenemos creado nuestra DLL, no hace falta mas que compilar el archivo.

image

Una vez compilado el archivo veremos que se crea una dll en el directorio donde tengamos guardado el proyecto.

image

Antes de continuar, expliquemos algunas líneas de código.

Esencialmente en el archivo dll.h se declaran las funciones que serán exportables por el archivo dll, para ello tenemos las líneas siguientes:

   1: #ifndef _DLL_H_

   2: #define _DLL_H_

   3:  

   4: #if BUILDING_DLL

   5: # define DLLIMPORT __declspec (dllexport) //Export de la DLL

   6: #else 

   7: # define DLLIMPORT __declspec (dllimport) //Import de la DLL

   8: #endif 

   9: DLLIMPORT void HelloWorld (void); //Prototipo de la función HelloWord

  10: #endif /* _DLL_H_ */

Mientras que en el archivo dllmain.c tenemos:

Declaración de librerías.

   1: #include "dll.h" // Nombre de la libreria donde se declaran los prototipos

   2: #include <windows.h> // biblioteca Windows.h para el uso de dll

   3: #include <stdio.h> //Biblioteca de funciones estandar

   4: #include <stdlib.h> 

Definición de la función HelloWord

   1: DLLIMPORT void HelloWorld ()

   2: {

   3: //En la definicion colocamos un MessageBox con el texto Hello World 

   4: //Sintaxis de MessageBox

   5: // MessageBox( 0, "Mensaje de Salida","Titulo de Ventana",Tipo);
Tipos: MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL | MB_OK
| MB_ICONEXCLAMATION |  MB_YESNO

   6:     MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);

   7: }

Declaración/prototipo de función DllMain:

   1: BOOL APIENTRY DllMain (HINSTANCE hInst/* Library instance handle. */ ,

   2:                        DWORD reason /* Reason this function is being called. */ ,

   3:                        LPVOID reserved /* Not used. */ )

Cuando Windows se vincula a una DLL de un programa, Windows llama a la función de la biblioteca DllMain. Esto significa que cada DLL debe tener una función DllMain.  La función DllMain debe ser definido como tal. Las palabras clave "BOOL", "APIENTRY", "HINSTANCE", etc, están todos definidos en <windows.h>.Por lo tanto, debe incluir ese archivo, incluso si no se usa ninguna API Win32 en su biblioteca

Esta función va a ser llamada automáticamente por cualquier programa que cargue automáticamente la librería.

Definiendo la función DllMain :

   1: {

   2:     switch (reason)

   3:     {

   4:       case DLL_PROCESS_ATTACH:

   5:         break;

   6:  

   7:       case DLL_PROCESS_DETACH:

   8:         break;

   9:  

  10:       case DLL_THREAD_ATTACH:

  11:         break;

  12:  

  13:       case DLL_THREAD_DETACH:

  14:         break;

  15:     }

  16:  

  17:     /* Returns TRUE on success, FALSE on failure */

  18:     return TRUE;

  19: }

APIENTRY es sólo una palabra clave que Windows utiliza internamente.Por lo tanto, no es necesario que te preocupes por eso.

La variable "hInstance" es el identificador de HINSTANCE para la biblioteca, y puede utilizar, o bien puede borrarlo.

Dentro de la definición de la función DllMain podemos encontrar la razón por la cual la biblioteca fue llamada, esto se controla con un switch siendo los siguientes casos:

DLL_PROCESS_ATTACH

En caso de que un programa se ha vinculado a la biblioteca por primera vez.

DLL_PROCESS_DETACH

En caso de que un programa se ha desvinculado de la biblioteca.

DLL_THREAD_ATTACH 
En caso de que un hilo de un programa se vinculado a la biblioteca.

DLL_THREAD_DETACH

En caso de que un hilo de un programa ha desvinculado de la biblioteca.

La función DllMain no necesita hacer nada especial para estos casos, aunque para algunas bibliotecas, podría resultar útil para asignar el almacenamiento de cada subproceso o un proceso nuevo que se está utilizando con la biblioteca.

La función DllMain debe devolver TRUE si la librería cargada con éxito, o FALSE si en la biblioteca había un error y no se pudo cargar. Si se devuelve FALSE, el programa mostrará un mensaje de advertencia y se cerrara.

La llamada de la biblioteca podrá producirse en dos ocasiones, una en la carga de la librería, siendo entonces el parámetro reason =  DLL_PROCESS_ATTACH y otra cuando se descarga la librería, en este caso, con el parámetro reason = DLL_PROCESS_DETACH.

Sin embargo, si no estamos interesados en saber alguna de las causas por la cual la biblioteca fue llamada por un programa, entonces podemos eliminar la sentencia switch y simplemente devolver un TRUE (return TRUE) .

Quedando de la siguiente forma:

   1: BOOL APIENTRY DllMain (HINSTANCE hInst 

   2:                        DWORD reason        

   3:                        LPVOID reserved    

   4: {

   5:     /* Returns TRUE on success, FALSE on failure */

   6:     return TRUE;

   7: }

 
Con eso tenemos una explicación de la sintaxis de nuestros dos archivos, el siguiente paso…. llamar la función  HelloWorld que se encuentra dentro de nuestra dll ( dll.dll ).
 

Llamando funciones del DLL desde un EXE

 
Para poder llamar nuestra función crearemos un nuevo “Código Fuente”.

image

Si nos pregunta si deseamos añadir el nuevo archivo al proyecto contestamos que No

image

 

El contenido de nuestro archivo será el siguiente:

// usar librería dinámica con enlazado dinámico
#include <windows.h>
#include <stdlib.h>
#include <iostream>
#include "dll.h"
//Puntero enlace
typedef void __stdcall (* FPTR)();

int main(int argc, char *argv[]) {
   FreeConsole();// Liberamos al programa de la consola
   HMODULE dllHandle = LoadLibrary("dll.dll");  // cargar librería 
   if (!dllHandle) {
      std::cout << "Error en la carga de dll.dll\n";
   }  else {
      FPTR llamada = (FPTR) GetProcAddress(dllHandle, "HelloWorld");
//Use GetProcAddress para devolver un puntero de función a una función en la biblioteca. 
      if (!llamada)
         std::cout << "Error al obtener direccion de HelloWord()\n";
      else llamada();

      FreeLibrary(dllHandle);    // descargar librería
//Una vez que haya terminado con un archivo DLL, y desea eliminarlo de la memoria,
//podemos llamar a la función FreeLibrary con identificador de módulo de la DLL. 
   }
//   system("PAUSE");
   return EXIT_SUCCESS;
}  

Guardamos el archivo como Llama_dll.cpp en el mismo directorio donde tenemos nuestro archivo dll.dll.

image

 

Cerramos DevC++ para cerrar nuestro proyecto dll.dev. y abrimos el archivo Llama_dll.cpp

image

Compilamos y ejecutamos

image

 

Y Wala! tenemos nuestro mensaje que definimos en la función HelloWord de la biblioteca  🙂 .

image

Es muy importante mencionar que si el archivo dll.dll no se encuentra en el mismo directorio donde ejecutamos Llama_dll.exe este no desplegaría el mensaje en pantalla.

Espero como siempre, les sea de utilidad 🙂 … dejo los archivos en el siguiente link:

Archivo_zipDescargar

 

Fuentes:

Un muy buen articulo que explica algunos conceptos

Wiki que explica a detalle la sintaxis

Ventanas Modales en DevC++

Documento Word que explica en muy resumidas cuentas como crear una dll

http://www.svetlian.com/dll/articulos_descripcion_dll.htm

http://www.zator.com/Cpp/E1_4_4b2b.htm#[2]

http://elblogroboticodepedro.weebercorp.com/2009/02/03/labview-31-crear-dll-en-c-con-dev-c-y-llamada-en-labview/

Video: http://www.youtube.com/watch?v=fzO9L6tlXDI

Anuncios

Conio.h en DevC++

Muchas veces en tareas que nos dejan realizar en casa surge el problema de que tenemos que programar en un compilador distinto que el de la escuela, por ejemplo: mientras que en el salón de clases tenemos Borland C++, en casa tenemos DevC++, no hay problema cuando los programas son sencillos, pero que sucede cuando llegamos a utilizar funciones “no estandarizadas” como por ejemplo: clrscr, gotoxy, cputs, putch, getch, getche, kbhit, etc… esto en DevC++ que tenemos en casa.

image

Lo primero que GRITAMOS al ver la pantalla de compilación es…
“Pero en la escuela funcionaba bien”.

Basándome en el post de Utilizar la librería conio en Dev-C++ describo los pasos a seguir, para poder utilizar la librería conio.h en DevC++.

Paso 1

Descargar el archivo conio1_31.zip ( oneDrive | Mega )

Paso 2

Descomprimimos el contenido del archivo conio1_31.zip

image

Paso 3

Seleccionamos el archivos libconio.a y lo copiamos al directorio: C:\Dev-Cpp\lib

image

Paso 4

Seleccionamos el archivo conio.h y lo copiamos en la carpeta C:\Dev-Cpp\include (en caso de que llegase a existir uno con el mismo nombre, pueden renombrar el original y copiar el conio.h del zip)

image

 

Paso 5

Seleccionamos los archivos 6-Console_conio.template , ConsoleConio_c.txt y ConsoleConio_cpp.txt y los copiamos en la carpeta C:\Dev-Cpp\Templates

image

 

Una vez echo los pasos anteriores, podremos probar nuestra librería conio , de la siguiente forma:

Abrimos Dev-C++ : Archivo –> Nuevo –> Proyecto

image

Si todo salió correctamente, aparecerá en la ventana de nuevo Proyecto un proyecto llamado: Consola + conio. La seleccionamos y presionamos Aceptar

 

image

 

Por default nos aparecerá un programa de prueba.

image

 

Lo compilamos y ejecutamos el código de prueba.

image

si obtenemos un resultado como la siguiente pantalla, es que todo salió bien 🙂

image

 

Espero les sea de utilidad, ya que en muchas escuelas utilizan Dev-C++ como compilador de C++.

Nota Extra:

En los comentarios del post original (fuente) viene un breve procedimiento, para que funcione con Windows 7 (para los que tengan problemas) y de igual forma se comparte otra forma, de hacer que conio.h funcione.

 

Fuente:
http://internetizados.wordpress.com/2009/02/13/utilizar-la-libreria-conio-en-dev-c/

Cuentas de correo para alumnos y egresados

La Dirección de Cómputo y Comunicaciones a través del contrato de licenciamiento vigente con Microsoft, ofrece la plataforma LIVE@EDU para la asignación de cuentas de correo electrónico a los alumnos y egresados de nuestro Instituto, estas hospedadas de por vida sobre un dominio propio del IPN en servidores externos al Instituto.(No aplica para el personal del IPN)

¿Cómo obtenerla?
Si eres alumno o egresado y aún no tienes tu cuenta de correo, llama al 57296000 ext. 51492 y solicítala. Si ya cuentas con una, llámanos para cambiarla por una nueva en la plataforma Live Edu con dominio @alumno.ipn.mx. No olvides tener a la mano tu CURP y boleta.

Concurso del 09 de mayo al 20 de mayo del 2011

FLYER_LIVEEDU5510

Bases del Concurso

1.- La vigencia de la promoción es del 09 de mayo al 20 de mayo del 2011.
2.- Sólo participarán los alumnos que activen su cuenta de correo IPN en el laboratorio de cómputo de su plantel durante el periodo de vigencia de la promoción. (ver planteles participantes)
3.- Si un alumno activa su cuenta en otro lugar que no sea el laboratorio de cómputo de su plantel no podrá participar en la rifa ya que los asesores de Microsoft llevarán el control de los alumnos que activan sus cuentas y serán quienes participen.
4.- Se rifarán 4 consolas de Xbox 360, una por cada plantel y los ganadores serán seleccionados mediante un sorteo con tómbola en la semana del 23 al 27 de Mayo en cada uno de los planteles participantes.
5.- Cada ganador recibirá su premio en su plantel en la fecha en la que se realicé el sorteo en su campus.
6.- Los planteles participantes son: UPIICSA, ESIME ZACATENCO, ESCA SANTO TOMAS, ESCA TEPEPAN
(mayor información en http://www.contenido.dcyc.ipn.mx/LiveEduPortal/)

 

Fuente:

http://www.upiicsa.ipn.mx/

http://www.contenido.dcyc.ipn.mx/LiveEduPortal/index.html

 

image
Se acerca peligrosamente la fecha … FLISOL 2011, donde la comunidad de software libre se reúne para difundir tecnología asociada al mismo, su objetivo principal es promover el uso de software libre, y UPIICSA participara de forma activa, la cita es:

Viernes 8 de abril a partir de las 9am y hasta las 6pm
UPIICSA
Edificio de Culturales.

 

Para mas detalles visiten el siguiente link: http://www.installfest.net/FLISOL2011/Mexico/UPIICSA

*A mi parecer hay dos temas muy interesantes que atender en la FLISOL UPIICSA 2011 (-Detección de arp-poisoning -Hardware libre en México )

 

desktop-1024x640

 

Ese mismo día el buen Alex por parte de foroupiicsa.net organiza un pequeño concurso en el cual pone a prueba el espíritu linuxero :P. Si quieres conocer las bases del concurso “Escritorios Linuxeros” así como los premios visita el siguiente link: http://foroupiicsa.net/?p=549

 

Y pues…. ya….. ponte a jugar…. libre!

Via | upiicsalibre.org & foroupiicsa.net

En un Escenario de PHP 5 trabajando con Oracle 9 , si de forma inexplicable (fantasmal) deja de funcionar OCI8, entonces… tienes un problema XD.

Este error suele ocurrir por que algún programa recientemente instalado, modifica las variables de entorno, para solucionarlo podemos modificar las variables de entorno de forma manual.

 

path

 

 

Botón Secundario en Mi PC –> Propiedades de sistema –> Pestaña Opciones avanzadas –> Clic en Botón Variables de entorno.

Editaremos la variable llamada PATH dando doble clic sobre ella.

 

 

 

 

Agregaremos al final de “valor de variable” -> ;C:\instantclient_10_2\

La línea que agregamos corresponde al directorio donde se instalo Instant client de Oracle (en nuestro caso se descomprimió directamente en C:\ ), recuerda sustituir este directorio según sea tu caso.

Damos clic en Aceptar , de nuevo Aceptar y para que los cambios se apliquen, reiniciamos el equipo.

 

*Nota:

Ojo con el ; que se antepone a la dirección.

Si lo que buscas es como lograr la conexión de PHP 5 con Oracle 9 visita el siguiente post (pronto)

 

Via | Sue

filezilla

Vallamos al grano, los sitios se guardan en archivos XML, simples y sin cifrar en la ruta:

Windows:

   1: C:\Documents and Settings\Usuario\Datos de programa\FileZilla\sitemanager.xml
   2: C:\Documents and Settings\Usuario\Datos de programa\FileZilla\recentservers.xml

Linux:

   1: /home/usuario/.filezilla/sitemanager.xml
   2: /home/usuario/.filezilla/recentservers.xml

Y con esto, “lloro amargamente” por que en las etiquetas XML esta mi nombre de usuario contraseña en texto plano (yo que te recomendaba tanto al amigo Filezilla) :

   1: <Server>
   2:             <Host>ftp.darkchicles.com</Host>
   3:             <Port>21</Port>
   4:             <Protocol>0</Protocol>
   5:             <Type>0</Type>
   6:             <User>darkchicles</User>
   7:             <Pass>MyPassword</Pass>
   8:             <Logontype>1</Logontype>
   9:             <TimezoneOffset>0</TimezoneOffset>
  10:             <PasvMode>MODE_DEFAULT</PasvMode>
  11:             <MaximumMultipleConnections>0</MaximumMultipleConnections>
  12:             <EncodingType>Auto</EncodingType>
  13:             <BypassProxy>0</BypassProxy>
  14:         </Server>

 

De buenas y primeras, ¡que felicidad!… así me los puedo trasportar en mi USB y consultar los password cuando se me olvide, todo de forma fácil y rápida.

Pero hablando de seguridad…. que… seguridad…. ¿Cual? … ninguna.

Referencia | Seguridad en Filezilla

Gracias a mi amigo Rodrigo, he conseguido recopilar algunos “plugs” en jQuery para realizar búsquedas y filtros, a continuación los muestro:

Filtrar un Gridview con Jquery

image

 

Una estupenda explicación de como crear tu propia búsqueda con jQuery, bastante fácil y entendible. Tiene un pequeño detalle con Internet Explorer pero es fácil de corregir 😉 (lee los comentarios")

URL: http://geeks.ms/blogs/gperez/

DEMO: Ver demo

Quicksearch

image 

Filtra ya sea por tabla completa ó bien por columna especifica, cuenta con un pequeño “loadig” y es personalizable para mostrar los resultados, además es sencillo de entender. Con una gran extensión de registros, llega a ser lento y hasta podría trabar tu explorador.

URL: http://lomalogue.com/jquery/quicksearch/

DEMO: http://lomalogue.com/jquery/quicksearch/super_table.html

TableFilter-0.2

image 

Este filtra al puritito estilo Excel, filtra por columna, a mi parecer bastante sencillo, pero tiene poca documentación y explicaciones, si te gusta investigar  y ver código adelante.

URL: http://blog.stekl.org/2009/12/nueva-version-plugin-jquery-para-filtrar-contenido-tablas/

DEMO:http://stekl.org/stuff/jqueryTableFilter-0.2/

 

Datatables jQuery

image

Este ultimo cuenta con paginación y contador de registros al momento de filtrar, su código fuente es un poco mas avanzado, como quien diría; es de bájame y úsame.

URL: http://www.datatables.net/

DEMO: http://www.datatables.net/

Nube de etiquetas