desarrolloMobile.NET Noticias

lunes, febrero 20, 2006

Name mangling, __declspec(dllexport), P/Invoke y DUMPBIN, (consideraciones varias)


El objetivo de este post es explicar consideraciones a muy bajo nivel de las librerias nativas desarrolladas con VC++ que quieran ser utilizadas desde código administrado mediante P/Invoke.

C++ fue el primer lenguaje que soporto las funciones sobrecargadas en entornos Windows. El problema de tener varias funciones llamadas igual, diferenciándose por el número y/o tipo de parámetros fue resuelto por el compilador asignando a cada función nombres 'especiales' para que el 'lincador' pudiera diferenciarlas. Esta técnica es conocida como 'name mangling'.
El problema se presenta cuando se quiere acceder desde un proceso externo a una de las funciones nativas. Pese a que el nombre de la misma es conocida por nosotros, el 'name mangling' ha intervenido y probablemente el nombre de la función internamente sea remotamente distinta de la original, aunque la libreria funcione correctamente.
VC++ soluciona este inconveniente mediante la macro __declspec(dllexport), que debe ser declarada en todas las funciones que sean susceptibles de ser llamadas desde un proceso externo. Asímismo deberemos indicar en un archivo .def el nombre de la librería y las funciones que seran exportadas precedidas por la palabra EXPORTS, ejemplo:


LIBRARY CPP_LibreriaEjempo
EXPORTS
Funcion1
Metodo2


Para asegurarnos que las funciones serán 'visibles' desde el exterior una vez compilada la libreria o bien queramos ver qué funciones lo són para una determinada librería que no hemos desarrollado nosotros, visual Studio .NET ofrece una herramienta muy interesante DUMPBIN. DUMPBIN está disponible desde la consola de comandos de Visual Studio .NET y deberemos pasarle el parámetro /EXPORTS para que no muestre la funciones 'exportables'. En la imagen un ejemplo de DUMPBIN de la libreria user32.dll.

martes, febrero 14, 2006

Congreso mundial 3 GSM en Barcelon

Ayer lunes se inauguró el congreso mundial de telecomunicaciones 3GSM, el más importante del mundo, en Barcelona. Gracias a la revista en la que colaboro habitualmente, dotNetMania, tengo la oportunidad de asistir al recinto ferial así como a distintas charlas sobre los más destacados temas del sector.

La impresionante puesta en escena de las más importantes compañías de telecomunicaciones a nivel mundial hicieron las delicias de los allí presentes; también durante estos días directivos de la categoría de Steve Ballmer (Microsoft), Ed Zander (Motorola), Olli-Pekka Kallasvuo (Nokia), Mr Wang Jianzhou (China Mobile) o Shane Robison (HP), realizarán charlas (Keynotes) sobre temas de actualidad y también de futuro.

Todas las novedades del congreso se publicarán en el resumen que dotNetManía está preparando así como la entrevista a David Fernández (Director de la División de Negocio de Movilidad y Dispositivos embebidos de Microsoft Ibérica), de la que tengo el placer de realizar; en definitiva trataremos de acercar, a los que no puedan asistir al evento, las novedades allí presentadas.

martes, febrero 07, 2006

Control de errores emitidos por las API de Windows en contextos P/Invoke

Durante una llamada a una API de Windows (sea Win32 o WinCE), mediante P/Invoke, suele ser muy probable que el código de error que devuelve la propia API no pueda ser recuperado, es decir que de alguna manera P/Invoke olvida ese valor. Además, llamadas del tipo GetLastError() pueden llevar a confusiones ya que desde que se genera el error en la primera llamada P/Invoke hasta la llamada de GetLastError(), el CLR puede haber llamado a otras APIs variando de esta manera el resultado de la esta última función.

Afortunadamente, el atributo SetLastError de DllImport asignado el valor true (el valor por defecto es false), permite ‘recordar’ a P/Invoke el resultado del error para el proceso en ejecución. La manera de obtener dicho resultado es utilizando el método GetLastWin32Error() de la clase Marshal (System.Runtime.InteropServices ), el cual devolverá el código de error emitido por la API de Windows. A partir de ahí lanzar una excepción con el código de error puede ser una opción.

Veamos un ejemplo en C# con la llamada a RasHangUp*

[DllImport(“coredll.dll”,SetLastError = true)] //si se utiliza en Win32 la llamada en a"rasapi32.dll"

public static extern uint RasHangUp(uint pRasConn);

if (RasHangUp (uiRas) != 0)

{

//si RasHangUp no devuelve 0, algo ha ido mal

int error = Marshal.GetLastWin32Error();

string msg = String.Format(“Error {0}”,error);

thrown new ApplicationException(msg);

}

* Para que no quede duda RasHangUp cierra una conexión RAS. La implementación en Win32 se hace llamando a rasapi32.dll y es:

DWORD RasHangUp(
HRASCONN
hrasconn
);

La implementacion en WinCE se hace llamando a coredll.dll y es:

DWORD RasHangUp(
HRASCONN Session
);

El parámetro de la declaración DllImport de RasHangUp puede pasarse también como IntPtr, int o uint, dependiendo del cáculo de referéncias.

lunes, febrero 06, 2006

¡Fin de semana Indigo!

Seguiendo el blog de José Murillo, y a raiz de su artículo en dotNetMania, número 21, Primeros pasos con Windows Communitation Foundation, el viernes decidí instalarme de una vez por todas Indigo (con la Pre-Release WinFX Runtime Components CTP de Enero) y comenzar a hacer 'mis finitos' con el estupendo ejemplo de José en dotNetMania.
El primer atasco fue que el sistema operativo sobre el que instalaba era en Español, y la CTP de sólo funciona sobre plataformas en Inglés. Así que una vez instalado el sistema operativo y añadido IIS sobre el mismo seguí la guía de instalación que encontré en http://www.windowscommunication.net/. A parte de las cerca de 2 horas que tardé en bajarme el SDK de poco más de 1Gb, no tuve más problemas y comencé a tocar código con una versión Express de C#. En WindowsCommunication.net hay dos Labs (Lab1,Lab2):
The Fundamentals of Programming the Windows Communication Foundation
Reliable and Transacted Messaging with the Windows Communication Foundation
Tengo que reconocer que no finalicé el primer Lab y ya estoy como en una nube, ¡es fantástico!
Trataré de finalizar los Labs, y expondré mis opiniones aquí, esperando poder escuchar las vuestras. Dos días, no más....