EL THUNKING
Como se comentó en la historia de OS/2, cuando éste fue diseñado era un Sistema Operativo de 16 bits, pensado para funcionar en máquinas equipadas con un 286. Cuando se realizó la primera versión de 32 bits, IBM decidió (de forma bastante desafortunada), excluir algunas llamadas de la antigua API, por considerarlas obsoletas. Este conjunto esta formado principalmente por todas las llamadas a los subsistemas. Dicen las malas lenguas que IBM decidió que el futuro eran los programas preparados para el Presentation Manager, por lo que no tenía sentido pasar el trabajo de incluirlas.
Sin embargo, IBM tenía claro que quería conservar la compatibilidad con todos los programas escritos para OS/2 1.x, por lo que tuvo que incluir un API de 16 bits, que aceptaba los parámetros en el formato del modo protegido del 286, y otra API de 32 bits, que trabajaba con el formato del modo protegido de los 386 o superiores. Esto significa que, en principio, no podemos llamar a estas funciones desde nuestros programas de 32 bits, pues la forma en que se pasan los punteros, por ejemplo, es distinta.
Ahora bien; dado que el API 16 y el API 32 son casi iguales, repetir todo el código de una para la otra suponía ocupar una gran cantidad de memoria y de espacio en disco, por lo que se realizaron las partes comunes dentro del API 32, y cada vez que un programa de 16 bits quería acceder a ellas, se realizaba un proceso de recorte (THUNKING), de modo que los datos eran convertidos al formato adecuado. Si dicho programa quería acceder a una función no perteneciente al API 32 (una llamada a un subsistema, por ejemplo), podía hacerlo directamente, pues al pertenecer exclusivamente al API 16, estaba escrita para trabajar únicamente con el formato del 286.
Lo interesante de esto es que nosotros podemos aprovechar estas rutinas de thunking para convertir nuestros parámetros al formato de 16 bits, y así llamar al API de los subsistemas. Para facilitarlo aún más, Robert E. Canup ha escrito una DLL, así como ficheros LIB y H para trabajar desde C, que hacen ver al compilador que son llamadas de 32 bits, y no de 16. Esto nos permite trabajar con estas funciones con total comodidad. El fichero lo tienes disponible simplemente pulsando aqui. Este fichero no lo necesitarás si usas el compilador EMX, el cual realiza automáticamente el proceso de Thunking.
Sin embargo, ni esta librería ni el EMX realizan el Thunking de forma completa. Cuando se trata de enviar un puntero entre los parámetros de la función, lo hacen bien, pero no si la rutina devuelve un puntero.
En el caso de que se nos devuelva un selector, o un selector y un offset, debemos usar una función que nos convierta estos datos en un puntero.
Por otro lado, en algunas funciones tenemos que pasar un puntero dentro de una estructura de datos (por ejemplo, cuando queremos cambiar los colores de la paleta con VioSetState). En estos casos tenemos que poder convertir dichos punteros al formato de selector:offset. El caso contrario no es preocupante, pues OS/2 puede trabajar directamente con punteros del tipo selector:offset.