Bienvenido!

¡Se bienvenido!

viernes, 4 de marzo de 2011

dlib C++ library. Guía de uso

Hoy voy a escribir cómo se usa esta impresionante librería (o biblioteca, que se supone que es la traducción literal jeje). Necesito hacer threads en el servidor para el juego Hotel y quiero que funcione en Windows y Linux, pero aunque la API de sockets se parecen mucho entre ambas plataformas, la de threads no se parece absolutamente en nada :)

Encontré la librería dlib en Google, y su web es http://dlib.net/
En ella tienen guías en inglés y montones de ejemplos, pero yo voy a poner lo más básico para ponerla en tu proyecto o Makefile.

Lo primero es bajarla (actualmente la versión 17.36) y descomprimir la carpeta 'dlib' que hay dentro del zip (Ruta: dlib-17.36.zip\dlib-17.36\dlib). Vienen otras carpetas, pero la que necesitas para tu proyecto o Makefile solo es esa; las demás son de documentación y ejemplos.

La guía original dice que te asegures de que la carpeta donde instalas la 'dlib' esté en la ruta de inclusiones del proyecto o compilador, aunque yo no tuve que hacerlo puesto que la he metido en la propia carpeta de fuentes del programa, lo que me permite hacer "#include dlib/threads.h" directamente.

Ahora, dependiendo de qué se esté usando de la librería, se necesita el fichero "dlib/all/source.cpp" o no. Esto se debe a que casi toda la librería se compone de ficheros de cabecera (.h) pero hay excepciones, como los threads, en los que lo necesitas. La forma más sencilla es incluir ese fichero en la solución de Visual Studio y probar a compilar para ver si funciona; posteriormente, quitarlo a ver si da errores o no :)

En la documentación tienes ejemplos de uso de cada parte de la librería, pero es tan fácil como cualquier otra clase que importes al proyecto.

Ahora, la forma de utilizarla en Linux es la siguiente:

Mantener la ruta igual que expliqué antes, o meterla en una carpeta global y modificar la ruta de includes del sistema o del Makefile. En mi caso, la metí con la fuente y marchando.

Un ejemplo de Makefile: (cada línea que empieza aparentemente a 3 espacios, es un tabulador, si no, no funciona)

CC=g++
FLAGS=-g -Wall
LDOPT= -lpthread -lnsl

all: programa

clean:
   rm -rf *.o
   rm -rf programa

portable_socket.o: portable_socket.cpp portable_socket.h
   $(CC) -c $(FLAGS) -o portable_socket.o portable_socket.cpp

programa.o: programa.cpp
   $(CC) -c $(FLAGS) -o programa.o
programa.cpp

programa: portable_socket.o programa.o
   $(CC) -o programa portable_socket.o programa.o dlib/all/source.cpp $(LDOPT) -DDLIB_NO_GUI_SUPPORT

He puesto un par de objetivos como ejemplo, pero lo importante es el final, donde se ve que se incluye manualmente el fichero source.cpp y se pasa la opción DLIB_NO_GUI_SUPPORT. Esto viene en la documentación (How to compile, en la web oficial) y lo hice porque no tengo instaladas las cabeceras de desarrollo de todas las XWindows, si no, te fallará por todos lados.

En el caso de Linux, también se puede probar a quitar el source.cpp del Makefile a ver si chuta para tu caso :)

¡Espero que sirva la guía!

Clase socket portable Windows - Linux (C++ Portable sockets)

¡Saludos a todos!

He hecho una pequeña abstracción para utilizar sockets en Windows y Linux indistintamente.

La clase es bastante sencilla y basta con hacer un include de ella.

El constructor inicializa la API Winsock2 2.2 en el caso de Windows y en el de Linux, incluye las cabeceras necesarias. También nos da un socket listo para trabajar con él.

El destructor cierra el socket y libera los recursos.

Métodos públicos:

   portable_socket(void);
   int pbind (const struct sockaddr *addr, socklen_t addrlen);
   int plisten(int backlog);
   portable_socket* paccept(struct sockaddr *addr, socklen_t *addrlen);
   int pconnect(const struct sockaddr *addr, socklen_t addrlen);
   int psend(const void *buf, size_t len, int flags);
   int precv(void *buf, size_t len, int flags);
   void set_fd(SOCKET s);
   SOCKET get_fd();
   int get_last_error();
    ~portable_socket(void);

La 'p' de delante de cada nombre indica "portable", y no he metido funciones extra como sendto y recvfrom pero es bastante fácil añadirlas :)

Espero que sea útil :)

Enlace con el código: http://paste2.org/p/1280475 (Están los dos ficheros en el mismo paste)