El mundo del libro electrónico anda revolucionadillo

Primero una empresa saca una cosa rara que parece ser es un e-book reader pero que en la propia presentación casi se les escacharra (véase el vídeo con el aparato mostrando una raya más o menos por la mitad de la pantalla).

Luego nos salta iRex (recordemos que es una filial de Philips, que es la empresa que casi ha inventado todo pero siempre lo licencia a terceros) con su iRex DR1000. Este producto, que ya se puede comprar, es un lector con una pantalla de 10.4 cm en diagonal con la que al parecer se pueden leer cómodamente documentos en A4. También cuenta con una mejoradísima ergonomía respecto a la castaña del iLiad; destaca que al parecer se puede pasar página desde cualquier lado del aparato y cuenta con un diseño más suave que las abruptas e irregulares líneas del iLiad. Por supuesto es totalmente incompatible con el anterior, no podía ser menos.

También HanLin saca la versión 2.00 de su firmware para el LBook, el V3 y cualquiera de sus variantes. La principal mejora es que soporta el formato Mobipocket, tanto con DRM como sin él.

El Cybook GEN3 también actualizó el firmware hace muy poco, aunque más que novedades lo que trae son “estabilizaciones” y solución de bugs. No obstante, ahora tengo PDFs que no puedo leer y antes sí podía…

iRex, no nos convences

Voy a contar lo que nadie cuenta del nuevo modelo DR1000. No, no lo he comprado y espero poder resistirme a comprarlo. Y voy a explicar por qué. En primer lugar, lo que voy a comentar está documentado en la FAQ del producto, pero hay que leer entre líneas y tener la experiencia con su anterior producto. También está en castellano, gracias a Juan Luis Chulilla y su blog Tinta-e

En primer lugar, igual que con el iLiad, el producto no está acabado. Le faltan un montón de opciones que dicen irán añadiendo en futuras revisiones del software. ¿No le suena a nadie eso de algo? Lo mismo dijeron con el iLiad, y éste se quedó sin soporte para sonido, con un formato a medio hacer (el Mobipocket y todos los asociados como texto y html) y con más cosas prometidas y nunca cumplidas.

Es decir, prometen suspender a RAM y a disco, pero en futuras versiones. Prometen soportar futuros formatos, pero en futuras versiones. En fin más de lo mismo.

Pero la gran mentira está en la duración de la batería. En la FAQ, la pregunta te redirige a la página http://www.irextechnologies.com/batteries, en la que te cuentan lo mismo que para el iLiad. Se habla de 50 horas de duración, pero ya hay gente comentando que ni por asomo llega a esa duración…

Además, si veis el vídeo de la presentación (está en el primer enlace que pongo), veréis la espantosamente rapidez en pasar páginas… vamos, que ni un XT ejectuando el Autocad.

Actualización: No había visto el vídeo, pero por lo que parece el comercial dice que si se cae al suelo no se rompe, y el cometarista coge y lo deja caer desde la altura aproximada de una mesa… y se rompe, lo que se ve al final del todo tras los créditos. Otra razón más para no comprarlo. Fin de actualización.

Así que, como dijo aquél, “una y no más, santo Tomás”. Mi recomendación es no comprar el producto.

HanLin, en el camino correcto (pero aun te falta mucho)

A la espera de que HanLin saque su lector A4 (que lleva como un año anunciado pero siempre retrasado por problemas con la pantalla), tenemos la versión 2 del firmware para el LBook alias V3 alias <otros nombres>.

La gran novedad es el soporte Mobipocket. Pero casi como si no fuera novedad, porque la visualización de las tres fuentes disponibles es, por decirlo suavemente, peor que penosa. Leer se puede leer, pero parece que estemos delante de una pantalla CGA de las de 320 x 200 píxeles. Otro tema es el interlineado. Parece que es de dos líneas, y como ya han dicho por ahí, mucho espacio en blanco entre letras… Los mentideros comentan que en general ni funcionan los enlaces, ni el índice y que el uso de diccionarios es testimonial (al parecer sólo funciona un solo diccionario, el Longman nosequé).

En cuanto al PDF, sigue con el bug de la separación de las palabras, aunque parece que me han dicho cómo evitarlo con OpenOffice y guardando de forma especial. Ya veremos. Actualización: Efectivamente, la solución suministrada minimiza el bug tanto en OpenOffice como en Word: Hay que colocar todo el texto justificado, si hay una sola linea no justificada, se rompen las palabras. Gracias, Thiangu.

Otra cosa no he visto, pero seguro que actualiza y mejora algo el formato nativo, el FB2.

Pues eso es todo.

El RFOG ya no es lo que era…

Os cuento una histora que me ha ocurrido esta misma tarde. Aparte de emocionarme al ver el nuevo iLiad con pantalla A4 (gracias, Alfredo Novoa) y de pensar que, pese a haber corregido varios defectos (ahora lleva para pasar página en tres de los cuatro lados), supongo que la velocidad leyendo Mobipocket va a ser la misma que con el iLiad, así que paso de momento.

Bueno, ya me he ido por los Cerros de Úbeda. En fin, que la historia comienza con el cierre de una aplicación que tengo que montar mañana… En mi máquina de desarrollo se carga perfectamente, en las de prueba, también, pero creo una máquina virtual nueva a partir de la de seguridad completamente limpia (es el escenario que me encontraré mañana) y me peta en el arranque.

Como desde que los chicos de Microsoft piensan que no debemos saber qué ha petado, sino que lo mejor es mostrarnos un cuadro en el que nos diga que reinstalemos la aplicación, el que suscribe se queda a oscuras.

Bueno, no es problema. Instalo el depurador remoto, hago dos cambios en la configuración y lanzo la aplicación.

Me salta una excepción que me dice que no puede cargar un ensamblado. Bueno, deciros que la aplicación consta de un programa escrito en C# que a su vez se apoya en tres DLL nativas hechas en C++ (accedidas mediante interop de atributos), en una cuarta escrita en C++/CLI que hace de puente a una quinta, también nativa (accedida mediante interop IJW). Y finalmente un ensamblado hecho también en C++/CLI que más o menos es mi biblioteca de utilidades. Pues bien, la excepción estaba en esta última.

Vamos, un escenario algo complejo pero perfectamente «legal» dentro de la filosofía de Microsoft. Evidentemente mi primera comprobación es verificar que el ensamblado está y que se trata de la versión adecuada.

La siguiente comprobación se debe a varios bugs (yo los llamo bugs, quizás Microsoft los llame «features») de Visual Studio: Cuando uno genera ensamblados .NET desde un sistema operativo de 64 bits, el ensamblado se crea por defecto como «AnyCPU», lo que no sería ningún problema si luego ese ensamblado funcionara bien tanto en x64 como en x86. No voy a entrar en detelles, pero si arranca como «AnyCPU» todos los ensamblados no nativos han de ser «AnyCPU» o la aplicación terminará petando tarde o temprano (en general temprano, a la hora de la carga del esnamblado). O si arranca bien, hará cosas raras según se ejecute en x86 o en x64 (aunque sea bajo Wow64, especialmente bajo Wow64).

Pues bien, uno abre el «Configuration Manager» y lo deja todo en Win32 y x86… borrando las configuraciones mixtas. Claro está, esto funciona hasta que al IDE le salga de los cojones pasar hasta el culo de ti y cambie algunas opciones a x64, otras a x86, otras a Win32, te cree varias configuraciones mixtas, y use cualquiera de ellas. Ayer cerraste el IDE funcionando y hoy ya no funciona.

Vale, también miré eso: estaba todo bien, pero el puñetero programa se negaba a cargar el puñetero ensamblado porque decía que faltaba el propio puñetero ensamblado o alguno de sus puñeteros componentes… ¡Pero si está solo, si es un p*to ensamblado mixto DLL! Bueno, se negaba a cargarlo en una configuración limpia, porque en mi portátil, en el ordenador de pruebas, y en dos o tres máquinas virtuales funcionaba bien…

Abro una máquina virtual de extrangis que tengo con una copia del Visual Studio 2008. Lo recompilo todo. Lo paso a la máquina virtual y… y…

¡Joder, funciona!

La única diferencia entre mi máquina de desarrollo y esa virtual es el sistema operativo. Bueno, no realmente, había otra diferencia por la cual yo quería compilar en la real y no en la virtual. Se trata de una diferencia que luego contaré. En mi cabeza en ese momento la única diferencia posible era el sistema operativo. Pero evidentemente me negaba a que la diferencia fuera esa… No puede ser que ocurra algo así, sería la debacle y la vergüenza más espantosa de Microsoft, así que sigo probando cosas.

Copio otra máquina virtual. Reinstalo el runtime del .NET, le doy una vuelta por Windows Update, le pongo una vela, me voy al patio a gritar, lo amenazo con la recortada, me acuerdo de algunos parientes cercanos y lejanos… y nada.

Me voy a dar una vuelta por ahí. Saco la basura. Miro el cielo. Vuelvo. Nada, que no funciona…

…….

Al final, claro está, lo encontré. ¿Sabéis qué era?

EL P*TO RUNTIME DE VISUAL C++

Me explico. Al ser un ensamblado hecho en C++/CLI compilado sólo con /clr, necesita el Runtime de C++ frente a C# que en general no lo necesita. Yo eso lo sabía, y sabía que tenía instalado el runtime en la máquina virtual limpia y en todas las demás… pero ¡tenía el del Visual Studio 2008, no el del Visual Studio 2008 SP1!

Es por eso el título de la entrada: efectivamente, el RFOG ya no es el que era, ya que en primer lugar era consicente de que al Visual Studio 2008 instalado en la máquina virtual le faltaba el SP1, y, como es lógico, yo quería recompilar con el que tiene el SP1 instalado. Pero me había obcecado en que la diferencia era el sistema operativo (XP frente a Vista). En segundo lugar, es una regla grabada a fuego: los runtimes. Nunca olvides los runtimes. Y, evidentemente, hacer la conexión entre una cosa y la otra era algo trivial… si no te ofuscas como me ha pasado a mi.

Así que ya sabes, si las cosas no funcionan, relájate, tómate un café, vete a dar una vuelta, y vuelve después.

C++: Insertar un ejecutable dentro de otro… y luego ejecutarlo

Vamos a explicar cómo tomar un ejecutable (o cualquier otro fichero binario), insertarlo dentro de un ejecutable y posteriormente cómo recuperar ese ejecutable embebido, soltarlo a disco y ejecutarlo. El escenario típico es borrar el propio ejecutable que actúa como hospedante, pero seguro que a las mentes calenturientas de mis lectores se les ocurren más aplicaciones.

El problema no existía en Windows 95 y siguientes: un programa podía borrar su propio ejecutable y terminar sin ningún problema (o casi). Pero en los núcleos NT hacer eso es harina de otro costal. Teóricamente se puede hacer mientras que el ejecutable a borrar no abra ningún handle… pero evidentemente cualquier ejecutable suele abrir no uno, sino infinidad de ellos.

La solución consiste entonces en disponer de dos ejecutables en disco. El primero hará su tarea y llamará al segundo antes de terminar, que tras unos instantes procederá a borrar el primero, quedando éste último en disco. Pero entonces tenemos que distribuir dos ficheros y colocarlos en el mismo sitio, por lo que la mejor solución es que el primero contenga al segundo en sus entrañas y lo use a voluntad. Incidentalmente el segundo podría decir a Windows que lo borre en el siguiente reinicio, pero no vamos a entrar en detalles sobre esto.

Primer paso: Insertar el ejecutable

Suponiendo que tengamos ya construido nuestro ejecutable (que vamos a llamar “borra.exe”), insertar un recurso del tipo RCDATA en un fichero ejecutable es una tarea trivial. Basta con abrir el fichero de recursos del ejecutable (el .rc) como texto e insertar la línea:

ELEXE RCDATA «..\final\Win32\Release\borra.exe»

Recompilamos y ya tenemos el ejecutable como recurso binario embebido en nuestro propio ejecutable. Evidentemente no estamos limitados a ningún tipo de archivo en concreto. Podríamos hacerlo incluso con recursos normales (mapas de bits, iconos, cadenas, etc.). La única diferencia es la forma de recuperar un recurso binario de uno almacenado como estándar.

Segundo paso: Sacar el ejecutable y ponerlo en disco

Cuando queramos volcar nuestro ejecutable a disco, debemos ejecutar algo parecido a lo siguiente:

HRSRC res=FindResource(NULL,_T(«ELEXE»),RT_RCDATA);
if(res==NULL)
     return GetLastError();

int size=SizeofResource(NULL,res);
HGLOBAL hRes=LoadResource(NULL,res);
unsigned char *pRes=(unsigned char *)LockResource(hRes);

HANDLE hFile=CreateFile(szT2Path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
if(hFile==INVALID_HANDLE_VALUE)
     return GetLastError();

WriteFile(hFile,pRes,size,&bytesWritten,NULL);
CloseHandle(hFile);

ShellExecute(HWND_DESKTOP,NULL,szT2Path,NULL,NULL,SW_SHOWNORMAL);


El primer paso consiste en llamar a FindResource con el nombre y el tipo de recurso. Si nuestro fichero hubiera estado almacenado en otro lugar que no fuera nuestro propio ejecutable, el primer parámetro a pasar es la instancia del fichero externo.

Tras tener un handle válido, tenemos que mirar el tamaño que ocupa el recurso almacenado, lo que hacemos con SizeofResource.

Ahora viene cargar el recurso en memoria y obtener un handle de memoria (LoadResource). Pero todavía no podemos acceder a los bytes de nuestro fichero, debemos bloquear el acceso a los mismos mediante LockResource, lo que nos devolverá un área de memoria accesible.

Aquí el autor lo ha asignado a un buffer de caracteres sin signo, pero realmente cualquier tipo de dato es perfectamente válido, aunque tenemos que tener en cuenta de no guardar ningún byte de más en el fichero final. Haciéndolo con un buffer de caracteres nos aseguramos de guardar el tamaño correcto.

Ya solo nos queda guardar el buffer a disco y hacer la llamada para ejecutar el fichero extraído.

Quizás nos preguntemos por qué no hemos liberado la memoria apuntada por pRes: está expresamente descrito en la documentación de la MSDN: no debemos hacerlo nosotros, ya lo hará el sistema cuando corresponda.

Consideraciones finales

Evidentemente una solución más sencilla sería marcar el propio ejecutable para ser borrado en el siguiente reinicio en lugar de hacer toda esta parafernalia, pero a veces puede no interesarnos que dicho fichero esté en disco hasta ese momento.

De todos modos aplicaciones para esto las hay a montones. Soltar un ejecutable que haga algo, termine y luego sea borrado por el programa principal, forzar un reinicio del programa principal, distribuir un solo exe que luego suelte todos los ficheros que necesite…

Hemos leído: Charles Petzolod: Code

 


Code (Dv- Undefined)El subtítulo del libro es: The Hidden Language of Computer Hardware and Software, que traducido al castellano quedaría como El lenguaje oculto del hardware y del software de los ordenadores. Y eso es lo que es la obra.


En apenas trescientas ochenta y pico páginas Charles Petzold recorre la estructura y el funcionamiento de un ordenador moderno. Y no lo hace nada mal. Yo más bien diría que lo hace de forma inmejorable, ya que combina la rigurosidad más absoluta con la magia de las explicaciones coherentes e incrementales. Como él mismo dice, en este libro no va a encontrar el lector grandes y vistosos gráficos mostrando de forma elemental conceptos que de tan sencillos dejan más duda que comprensión.

Se trata de un libro que pudiéramos llamar hardcore, pero no por eso es menos entendible. La profundidad de las explicaciones se pierde en la maravillosa forma en que están hechas. Personalmente me ha vuelto a mis tiempos de estudiante de electrónica digital y de microprocesadores, haciéndome continuos guiños y recordándome aquellas arduas sesiones de estar primero escribiendo el programa en ensamblador, luego traduciéndolo a código máquina y finalmente tecleándolo con una botonera hexadecimal… para que un brazo de robot girara sobre sí mismo o abriera y cerrara la pinza…

El autor comienza con una explicación sobre qué es un código de comunicación (nos habla de Braille, de Morse, de bombillas apagándose y encendiéndose) y nos construye y explica un aparato de Morse. Entre tanto hemos dado un curso básico de electricidad, viendo cómo circula la corriente, cómo funcionan los relés y alguna que otra cosa más.

Luego nos explica cómo funciona el sistema decimal, el binario, el octal, el hexadecimal, y cuando nos damos cuenta estamos construyendo puertas lógicas (AND, OR, etc.) y hemos asistido a un curso sobre lógica formal.

Casi sin darnos cuenta al rato estamos construyendo un oscilador, un sumador y un restador con relés, y de paso aprendemos el complemento a dos y cómo restar sumando.

Un par de capítulos después nos descubrimos inmersos en básculas Flip-Flop y tipo D… Y cuando levantamos la cabeza de libro hemos construido una memoria de 64Kbytes, un contador y otros varios elementos básicos.

Lo bueno del libro es que fluye de forma continua, se desplaza de lo más sencillo a lo más complejo de forma secuencial y sin aparente aumento de dificultad, para descubrir que estamos estudiando un ordenador casi completo. Hemos visto cómo funciona el código máquina, hemos visto las instrucciones aritméticas, de salto condicional para hacer bucles y lo más importante de todo es que lo entendemos. Apenas nos cuesta comprender cómo están cliqueando los relés dentro de nuestro ordenador (es un decir), y comprendemos cómo arranca y empieza a funcionar. Ciertamente es un libro mágico porque pese a lo riguroso y formal de su contenido es perfectamente entendible.

Adelanta y atrasa, recorre un gran trecho hacia adelante y luego recopila y se recrea en conceptos. De repente nuestro ordenador de 8 bits (porque sin darnos cuenta hemos construido tal aparato) pasa de estar hecho de relés a ser de válvulas (y de paso nos damos una vuelta por los primeros ordenadores, el ENIAC, MULTIVAC, etc). Y un poco más tarde está construido con tecnología TTL o CMOS, y de repente se nos presentan los microprocesadores, pero no sin antes haber recorrido la mente del doctor Atanasof y de Hollerich, pasando por lo que antes era IBM…

En ese momento, si nos ponen en la mano un 8080 y un chip de memoria seríamos capaces de construir nuestro ordenador del igual modo que lo hicieron Wozniak y Waine.

Pero el libro no termina ahí, sino que sigue subiendo de nivel hasta explicarnos por qué necesitamos un sistema operativo. De hecho, siguiendo con la tónica del libro, casi sin darnos cuenta estamos viendo la necesidad de un sistema operativo; es decir, tras tener un aparato programable Petzold nos hace evidente lo evidente.

Números en coma flotante, lenguajes de alto y bajo nivel, entornos gráficos. En lugar de explicárnoslo, el libro nos hace sentir la necesidad de ellos… y entonces nos los explica.

Para finalizar: un libro muy bello, interesante y admirablemente construido. Lástima que no esté traducido al castellano, porque no creo que haya otra obra igual. Aunque por un lado tenemos los libros de electrónica digital y por otros los de informática básica, ninguno enlaza y engloba todos los conceptos e ideas de una forma tan coherente, incremental, lógica y bella.

Sólo hay un punto oscuro en toda la obra: el autor no nos explica la unidad de decodificación y de ejecución del ordenador que nos construye. Ciertamente poner en marcha algo así es un tema arduo y complejo en demasía, pero hubiera sido la guinda que corona el pastel… De todos modos, pese a esa falta, la obra no pierde absolutamente nada de su valor.