Tutorial consumir DLL C++ en C#

1.707 visualizaciones

Publicado el

Claro que si, como su título lo indica, la raíz de este tutorial es porque hay muy poca información en español sobre como realizar este tipo de tareas.



Entonces, me veo en la necesidad de hacer algo útil y que sirva para aquellos que no dejamos de utilizar el lenguaje C/C++ para nuestras tareas rutinarias.

Publicado en: Tecnología
0 comentarios
1 recomendación
Estadísticas
Notas
  • Sé el primero en comentar

Sin descargas
Visualizaciones
Visualizaciones totales
1.707
En SlideShare
0
De insertados
0
Número de insertados
608
Acciones
Compartido
0
Descargas
14
Comentarios
0
Recomendaciones
1
Insertados 0
No insertados

No hay notas en la diapositiva.

Tutorial consumir DLL C++ en C#

  1. 1. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Tutorial Consumir desde C# DLL desarrollada en C++ Ingredientes: -Visual Studio Express 2013 for Windows Desktop -Dependency Walker -Conocimientos de C y C++ (un poco más de lo básico) -Autodidacta ¿Por qué? Porque si no disponemos de una aplicación para ofuscar el código fuente en C# o bien para ofuscar las librerías creadas en C#, entonces la solución viable sería construir una librería en C++, porque hasta el momento no conozco una aplicación para descompilar librerías desarrolladas en C++ y que te devuelve el código fuente. Todos sabemos (bueno eso creo…) que existen aplicaciones para descompilar código C#, de las cuales puedo mencionar “ILSpy” http://ilspy.net/, de la cual me he favorecido muchas veces. Hay aplicaciones de pago para ofuscar código C# muy buenas, como por ejemplo: Crypto Obfuscator For .NET http://www.ssware.com/cryptoobfuscator/obfuscator-net.htm de la cual también puedo decir que, saca la tarea para lo que se necesita. Por último: Lo nativo (Win32) siempre será mejor que lo interpretado.
  2. 2. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Pasos: 1. Crear solución en Visual Studio Express 2013 de tipo C++ New ProjectVisual C++Win32 Project: Para este ejemplo, el proyecto tendrá el nombre “MyDll” Luego:  En el asistente “Win32 Application Wizard”: Next  En “Application type” seleccionar “DLL”  Por ultimo “Finish”. 2. La DLL devolverá de C++ a C# los siguientes tipos de datos: C++ C# LPTSTR string char * string int int double double LPSTR string const char * IntPtr Así mismo se devolverá una estructura que contiene todos los tipos de datos de la tabla anterior.
  3. 3. @_jdepaz José de Paz desarrollo.escuintla@gmail.com 3. Crear las funciones de retorno de valores: Para realizar este paso, es necesario agregar un archivo de encabezado (header), el cual se llamará “MyDll.h”, entonces, seleccionar el proyecto de la solución y proceder a agregar un nuevo ítem, el cual será de tipo “Header File (.h)”. En este archivo se incluirá el encabezado “#include <windows.h>” y se agregarán las definiciones para la exportación de funciones, es decir el archivo “MyDll.h” deberá quedar así (por el momento):
  4. 4. @_jdepaz José de Paz desarrollo.escuintla@gmail.com 4. Definir las funciones de exportación: Las funciones a exportar serás las siguientes:  LPTSTR ExportaLptstr()  char * ExportaCharA()  int ExportaInt()  double ExportaDouble()  LPSTR ExportaLpstr()  const char * ExportaConstChar()  BOOL ExportaEstructura(MiEstructura *miEstructura) En el archivo “MyDll.h” las funciones de exportación quedarán así:
  5. 5. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Si realizamos una compilación (Rebuild) previa del proyecto (Ctrl+Alt+F7), la misma se debe realizar sin ningún problema (al menos eso espero): 5. Implementar las funciones en el archivo “MyDll.cpp” Las funciones deben ser implementadas y por supuesto tienen que devolver el tipo de valor según la definición. Si alguien se pregunta el por qué se está utilizando -extern “C”- en cada función y se supone que es una DLL en C++, al terminar este proceso encontrarán la respuesta. A continuación la implementación de cada función:
  6. 6. @_jdepaz José de Paz desarrollo.escuintla@gmail.com
  7. 7. @_jdepaz José de Paz desarrollo.escuintla@gmail.com 6. Compilar Nuevamente compilar el proyecto, y sin esperar, no tiene ningún motivo para darnos algún error: 7. Configuración de compilación en “MyDll.dll” Si, resulta que: cuando se invoca la función en C#:
  8. 8. @_jdepaz José de Paz desarrollo.escuintla@gmail.com La aplicación termina con código de error, entonces para que esto no suceda, es necesario establecer una propiedad en la compilación de la DLL: La configuración se realiza accediendo a las propiedades del proyecto (ya saben, haciendo clic con el botón derecho, etc., etc.) 8. Comprobar MyDll.dll con “Dependency Walker” Hay una aplicación llamada “Dependency Walker”, si bien su nombre lo expresa muy bien para que nos sirve, en este caso nos servirá para verificar las funciones que tiene expuestas la DLL que acabamos de compilar. Esta aplicación la pueden encontrar y descargar utilizando el buscador de su preferencia.
  9. 9. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Entonces, utilizando “Dependency Walker”; busca la carpeta de depuración en donde encontrarás el archivo “MyDll.dll”, procedemos a abrir la aplicación “Dependency Walker” y luego a cargar la DLL, entonces se mostrarán las funciones expuestas: 9. Crear proyecto en C# En la misma solución, vamos a agregar un nuevo proyecto, en este caso un proyecto C# de consola, el cual se llamara “TestMyDll” (es una sugerencia, porque puede ser a como bien te guste):
  10. 10. @_jdepaz José de Paz desarrollo.escuintla@gmail.com 10. Importar funciones de la DLL “MyDll.dll” Bien, ahora en la aplicación de consola vamos a proceder a importar las funciones que nos provee la DLL. NOTA: La DLL “MyDll.dll” tiene que estar presente en la ruta donde se encuentra el ejecutable de la aplicación de consola, en este caso como estamos en modo depuración, se tiene que copiar la DLL en la carpeta “Debug” o bien “Release” si así fuera, por ejemplo:
  11. 11. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Seguimos, en “Program.cs” (que es donde está definida la función principal; o sea “Main”) vamos a escribir un poco de código en donde se declaran las funciones que exporta la DLL “MyDll.dll”, y más o menos nos debe quedar así:
  12. 12. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Si compilamos y ejecutamos, posiblemente no veamos la salida, entonces tendríamos que poner un punto de interrupción y efectivamente veremos el resultado que nos devuelve la función: Procedamos a realizar el respectivo análisis:  La función de la DLL en C++ está definida así: Esto quiere decir: cuando una función que devuelva un tipo de dato “char *”, en C# se debe recibir como “IntPtr” y luego utilizar
  13. 13. @_jdepaz José de Paz desarrollo.escuintla@gmail.com la función Marshal.PtrToStringAnsi para convertir el valor del puntero a “string” respectivamente. Esta fue la primera toma de contacto, ahora resta declarar las demás funciones: Y como verán, en las funciones que devuelven “LPTSTR” y “LPSTR” también se declaran los valores de retorno como “IntPtr”. Analizando un poco: las funciones que devuelven “cadenas de caracteres” se declaran como “IntPtr” y luego se utiliza la función la función Marshal.PtrToStringAnsi respectivamente.
  14. 14. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Ahora, se invocan (o se llaman) las funciones para su respectivo uso: Y por supuesto, seguido realizamos la compilación y ejecución en modo “Debug”, y ponemos un punto de interrupción en el “return” y sólo resta ver los resultados que tienen las variables: _recibeCharA, _recibeConstChar, _recibeDouble, _recibeInt, _recibeLpStr y _recibeLptStr:
  15. 15. @_jdepaz José de Paz desarrollo.escuintla@gmail.com Con zoom:
  16. 16. @_jdepaz José de Paz desarrollo.escuintla@gmail.com 11. Función que devuelve una estructura Queda pendiente para una próxima entrega…

×