Mi iLiad está enladrilado, el desenladrillador…

… que lo desenladrille buen desenladrillador será.

En fin, que más chapuzas.

No suelo usar mucho el iLiad últimamente porque me valgo del Gen3, que es más manejable y la batería le dura casi una semana (de lejos los 8.000 cambios de página prometidos). Lo enciendo todas las semanas y miro el nivel de batería para evitar que se descargue. Pues bien, en una semana ha pasado mágicamente de estar a un 80% a estar completamente descargada.

Bien por el medidor de la misma.

Tiro a encenderlo tras haberlo cargado del todo y me encuentro con que la fecha está en el 2003… Miro el manual y la forma de actualizar la fecha es pasar por el iDS, que es el sistema online de actualización.

Pues lo conecto, hace una actualización de algo y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia… y se reinicia…

Creo que con eso basta.

No se apaga del botón de apagado…

Pues bien, reflash al canto. Me bajo el software oficial, lo meto en la CF y mantengo pulsado el botón de la derecha de arriba… por suerte en el reinicio coge el boot flash y se pone a flashear… pero se queda la pantalla de bienvenida del reflasheo y no avanza.

Miro la imagen y el fichero de comandos (config.txt)está mal: lo que debería estar en tres líneas está en una. Es decir, debería poner:

kernel
initrd
applications

y pone

kernelinitrdapplications

Lo corrijo, reflasheo, y funciona.

Por supuesto, he perdido toda la configuración y personalización, amén de tener la versión 2.10 en lugar de la 2.12..

Vuelvo a entrar en el iDS y actualizo a la 2.12.. y seguimos con los reinicios.

Así que adopto el método más drástico de todos: añado «format» al config.txt y reflasheo de nuevo. Así lo pierdo absolutamente todo lo que tenía en el aparato. Pero resulta que no funciona y se reinicia continuamente…

Finamlemte, tras pelearme un largo rato con ecodings, formatos de SD, otros menesteres (y unos cuantos flasheos fallidos más), parece ser que se ha actualizado correctamente y está funcionando bien.

Gracias, iRex (Philips) por hacer las cosas bien… espero que se note la ironía.

BUG: El bug del bool en interop desde C++ nativo

Basta que uno plante un circo para que le crezcan los enanos, y como se puede comprobar si uno mira al jardín de la vecina esa que está tan buena, a veces a uno le crecen sin estar bueno ni haber montado la carpa.


No sé en qué pensarán estos señores de Microsoft, pero que el bug venga arrastrado desde por lo menos 2002 y no esté solucionado clama al cielo. Pero antes de despotricar –que lo haré-, vamos a ver en qué consiste.


Uno tiene una inocente DLL que posee una función que devuelve un valor de tipo bool de C++. Algo así:

extern «C» MIDLL_API bool dllFncDevuelveBool(unsigned char id);

Ahora hace el envoltorio manejado para ser usado en otro lenguaje .NET:

[DllImport(«dllNativa.dll»)]
extern public static bool dllFncDevuelveBool(byte id);

Y a partir de ese momento comienza a utilizarla en su programa, digamos, escrito en C#. Pero pronto uno descubre que… bueno… la función


¡¡siempre retorna cierto!!


Uno empieza a meterse con el depurador y escribe código como este:

bool resp=DLLAdaptor.dllFncDevuelveBool(m_device.ID);
if (resp == false)
MessageBox.Show(«No puedo en este momento.”);»

Pone un punto de interrupción en el comparador y ve que, mientras que la ventana de variables automáticas le dice que la llamada a dllFncDevuelveBool devuelve falso, resp vale cierto. Y para más inri, si entra en la función nativa, en todos lados ve que se está devolviendo falso.


Como el autor tuvo hace unos días un embrollo de narices con algo muy parecido, se pone a buscar la misma solución que encontró con anterioridad. La cosa tuvo su miga, ya que había una función que debía hacer un salto a otra parte del código cuando varias condiciones fueran ciertas, pero el salto se producía siempre o casi siempre, no importaba si se cumplía el comparador o no… Tras varios días de buceo descubrió que se estaba pisando variables, entre ellas las que estaba comparando. El tema era bastante complejo, porque quien pisaba era un hilo y cuando se realizaba la inspección de la variable tenía su valor correcto, pero cuando el código se ejecutaba (dos o tres instrucciones ensamblador después), ya se había pisado y despisado… Vamos un tema de “puntero loco sincronizado”.


Bueno, como la situación era similar, aunque no igual (lo anterior era en C++ puro, en este caso había interop de por medio), el autor se puso a buscar su “memoria pisada” sin encontrar nada de nada.


Al final, cuando estaba hasta las mismísimas narices del tema, se le ocurrió googlear y cuál no fue su sorpresa cuando se encontró entradas, del 2002, como ésta: http://groups.google.com/group/microsoft.public.dotnet.languages.vc/msg/a6d9c1e3015207f0?hl=en&lr=&ie=UTF-8&oe=UTF-8 y esta otra del 2005: http://bytes.com/forum/thread267443.html.


Finalmente, era un bug del Interop de .NET ¡¡que lleva por lo menos 6 años sin ser resuelto!!, y encima es un bug estúpido cuya corrección seguro que apenas requiere una línea de código fuente…


Es decir, cuando una función nativa devuelve un valor booleano nativo de C++, el Interop se equivoca y retorna siempre cierto.


La corrección pasa por colocar algo así en la firma manejada:


[DllImport(«dllNativa.dll»)]
[return: MarshalAs(UnmanagedType.I1)]
extern public static bool dllFncDevuelveBool(byte id);


Vaya usted a saber qué significa I1.


Lo que más me toca las narices del tema es que lleve por lo menos 6 años sin resolver, o si fue resuelto ha vuelto a aparecer. ¿Tan difícil es comprobar algo como esto? Ciertamente siento vergüenza ajena del tema, que algo tan sencillo y tan evidente se conozca desde hace tanto tiempo, sea tan fácil de solucionar, y que nadie le haya hecho ni p*to caso.


En fin, que uno más para la colección: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=355665