From the category archives:

Programación

Snapshot: Hilos en C++ (Windows)

by Jorge Machin on September 26, 2008 · 0 comments

in C/C++, Programación, Snapshots, Windows

Una clase "quick and dirty" para crear hilos en cajas windows.

Encabezado:

#pragma once

#include <windows.h>

class CThread {

   public:

      // Constructor por defecto:

      CThread(void);

      // Destructor virtual
   
      virtual ~CThread(void);

      // Esta función inicia el hilo:

      bool start();

      // Esta función se debe sobrecargar con lo que tiene que hacer el hilo:

      virtual void run() = 0;

      // Esta función espera a que el hilo se detenga. Se debe llamar en el destructor de la clase derivada.

      void join();

   private:

      unsigned long id;

      void *threadHandle;

      static DWORD WINAPI entryPoint( void *pthis );

};

Archivo cpp:

#include "StdAfx.h"
#include "thread.h"

CThread::CThread(void) : threadHandle( NULL ) {

   MessageBox( NULL, "CThread::CThread", "Aviso", MB_OK );

}

DWORD WINAPI CThread::entryPoint( void *pthis ) {

   CThread *pt = ( CThread * ) pthis;
   pt -> run();
   return 0;

}

bool CThread::start() {

   threadHandle = CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE ) entryPoint, this, 0, &id );
   return true;

}

void CThread::join() {

   if ( threadHandle != NULL )

      WaitForSingleObject( threadHandle, INFINITE );

}

CThread::~CThread(void) {

   MessageBox( NULL, "CThread::~CThread", "Aviso", MB_OK );

   if ( threadHandle != NULL )   

      CloseHandle( threadHandle );

}

Como se dislumbra de los comentarios, para utilizarla es necesario crear una clase que herede de Cthrean y sobrecargar la función run con lo que debe hacer nuestro hilo.

{ 0 comments }

Snapshot: Obteniendo archivos HTTP en C++

by Jorge Machin on September 25, 2008 · 0 comments

in C/C++, Programación, Snapshots

Ya es común para un programador, no solamente el tener que leer archivos del disco duro local, sino también leerlos desde un sitio web; Ya sea un web service, una imagen o un XML. Afortunadamente la libreria libcurl resuelve el problema con muy pocas líneas de código.

En este post, pongo un pequeño ejemplo de como se usaría en C++ para pequeños programas de apoyo:

#include <string>
#include <iostream>

#include "curl/curl.h" 

class URLFile {

   public:

      std::string get( const std::string &URL ) {

         // Inicialización:

         CURL *curl = curl_easy_init();

         // URL a consultar

         curl_easy_setopt( curl, CURLOPT_URL, URL.c_str() );

         // Configuaración del callback

         curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, &URLFile::write_data);
         curl_easy_setopt( curl, CURLOPT_WRITEDATA, &data);

         // Obtén el archivo:
                       
         CURLcode result = curl_easy_perform(curl)

         // Al final hay que limpiar todo:

         curl_easy_cleanup(curl);

         if (result != CURLE_OK)  {

            return "";

         }

         return data;

      }

   private:
 
      // Variable que usamos para guardar el contenido del archivo:

      std::string data;

      // Callback que utiliza curl:

      static size_t write_data( char *buffer, size_t size, size_t nmemb, void *userp ) {

         int len = size * nmemb;
 
         if ( buffer != NULL ) 

            ( ( std::string * )  userp )->append( buffer, len )

         return len;

      }
 
};

int main() {

   URLFile file;

   std::string test = file.get( "www.machin.com.mx" );

   std::cout <<"Test:" <<std::endl <<test <<std::endl;

   return 0;

}

{ 0 comments }

En este post dejo unas reglas simples que he utilizando con el paso del tiempo y que me han funcionado para escribir programas con menos errores.

1. Reconocer que errar es humano

El primer consejo para controlar el número de errores en nuestro código, es reconocer que somos humanos y podemos cometerlos en cualquier momento. Por lo general, no es constructivo buscar culpables si no hay detrás una conducta crónica o casos evidentes de negligencia. La conducta correcta es crear las herramientas y metodologías que puedan reducir el riesgo de este hecho.

2. Probar, probar y probar

Uno de los elementos básicos del control de calidad son las pruebas al producto. Se debe revisar de forma ordenada el funcionamiento de los programas de principio a fin.

Por lo general, es recomendable que una persona ajena al diseño del proyecto también realice las pruebas, pues los programadores y diseñadores pueden estar ciegos a ramificaciones inesperadas al tener la tendencia natural de revisar los programas siguiendo el flujo de los algoritmos, del análisis o del mismo camino que utilizaron al programarlo.

Es recomendable apuntar o automatizar las pruebas en donde se tienen errores comunes o rutas complicadas para que sea lo primero que se revise para disminuir las iteraciones durante el proceso de control de calidad, o bien, se olviden de hacerlas.

Cuando el programa es suficientemente grande o involucra a varias personas, se recomienda tener un sistema centralizado donde se pueda reportar los errores y darles un seguimiento hasta su corrección.

3. Todo error se debe perseguir de oficio

Un reporte de error siempre es cosa seria. Generalmente, no es válido ignorarlo porque sólo le ocurre a un usuario o en una máquina en particular; hay que tener presente que si el error le ocurrió a alguien, le puede pasar a varias personas.

Si no se sigue este punto, quizás el error no haga estallar nada, pero puede aparecer en una demostración ante un posible cliente, creándonos mala reputación e incluso su perdida.

4. Un error emulado es un error corregido

Cuando un error se puede repetir fielmente es posible seguir trazas, colocar banderas de depuración o analizar la lógica hasta llegar a él. En teoría, si somos capaces de reproducir un error, deberíamos estar tranquilos porque estamos a unos pocos pasos de su solución.

5. Cuando ocurre un error, uno debe preguntarse: ¿Porqué ocurrió?, ¿qué se puede hacer para evitar que ocurra el mismo tipo de error en situaciones semejantes?

Este consejo es la parte medular para evitar errores. Si estamos cometiendo demasiados errores es porque seguramente llevamos una mala metodología y es el momento adecuado para detenernos a recapacitar en la forma de como se está trabajando.

6. Si un error aparece dos veces en un mismo lugar, es mejor re-escribir el código de otra forma o bien agregarle algo para evitar que pueda ocurrir de nuevo.

7. Para evitar errores al usar funciones, clases, etc; estas deben validar las entradas

Los errores no sólo pueden estar en nuestras funciones, sino en los programas que las utilizan. En grupos de trabajo es común que se pierda tiempo innecesario revisando funciones que no tienen errores y ya están revisadas porque presentan síntomas que apuntan a ellas cuando son los parámetros de entrada los que están mal.

8. Los programas deben registrar los errores en una bitácora (log)

Un error que nadie atestigua, no existe en nuestras mentes. Por eso, es muy importante agregar medios de monitoreo y registro de condiciones y situaciones anómalas para su posterior análisis. Si el error no puede reproducirse manualmente, con el tiempo y ayuda de banderas es posible darle seguimiento haciendo trazas hasta encontrarlo. Es muy importante que el mismo programa trabaje por nosotros y sea nuestro testigo de calidad en la busqueda de errores.

Sin entrar en mucho en detalle en herramientas automáticas para detección de errores, los programas que utilizan técnicas de orientación a objetos pueden usar "profilers" para contar el número de objetos que estamos creando y así ver si tenemos fugas de memoria o estamos desperdiciando recursos.

9. Si se tiene una solución complicada a un problema; seguramente no es la adecuada o va a provocar errores después.

Algoritmos complicados, trucos de programación o una solución estrafalaria, seguramente con el tiempo provocará errores y pérdida de tiempo a programadores inexpertos o a nosotros mismos después de algún tiempo. Es mucho mejor la programación "aburrida" donde uno ya sabe que va a pasar con solo ver unas pocas líneas de código.

10. Si no está roto, no es necesario arreglarlo

Esta regla es especialmente válida con código antigüo.

11. Tener código autodocumentable

La documentación en papel no se puede sustituir, pero tenerla dentro del mismo código es una buena costumbre para evitar errores al tener a la mano advertencias, rangos y cualquier otro tipo de información.

12. Leer o hacer pruebas de escritorio a nuestro código una vez que esta listo

Una vez que todo esta en su lugar y en perspectiva, es posible detectar faltas en los estándares, casos validados incorrectamente, código repetido y errores en la lógica. Es mejor si lo puede revisar rápidamente otra persona.

13. Cuando no encuentres un error, es buena idea platicarlo con alguien

Curiosamente, muchas veces me ha pasado que al explicar el problema un compañero de trabajo, he encontrado la causa del error dentro de mis propias palabras pues se acomoda mentalmente y se repite la lógica encontrando los absurdos. Además una mente externa suele tener mayor perspectiva.

14. La documentación debe incluir una bitácora de cambios al código que además registre los errores encontrados y sus correcciones

Al llevar un registro de los cambios es posible identificar históricamente a partir de que cambio surgió un error. Lo cual nos permite regresar a una versión anterior o darnos una idea de donde podemos empezar a buscar.

Nota:

Obviamente estos son consejos que pueden llegar a generar controversia y no son válidos en todos los contextos, metodologías o lenguajes de programación y no está por demás aclarar que al igual que otros de mis posts que estas reglas irán creciendo y puliendo con forme vaya teniendo tiempo libre.

Aquí los he presentado de forma sencilla, pero muchos de ellos están basados en algunas metodologías como programación extrema, fábricas de software, programación por contrato y otros que le recomiendo al lector que se familiarice con ellos.

{ 0 comments }