Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - [D4N93R]

#1001
Marshal - Interactuando entre managed y unmanaged memory.

Antes de comenzar con el tema tenemos que tener en cuenta que toda aplicación en .Net se ejecuta bajo una porción de memoria administrada por el CLR y no interactúa directamente con la memoria nativa. (Para conocer más, puedes revisar este post: Conceptos de la arquitectura .NET Framework escrito por Mace Windu.)  :)

Ahora que conocemos cómo funciona el framework, podemos entender qué es Marshal. Marshal es una clase que está en el namespace System.Runtime.InteropServices, que casi nadie habla de él y que no muchos han visto, y lo que hace es mediar entre ambos entornos. Imaginen un bar de lujo (Managed Memory), la calle (Unmanaged Memory) y el portero (Marshal), no es más que eso, si quieres entrar o salir del bar, vas a tener que pedirle permiso a Marshal. En pocas palabras marshal nos permite copiar data de un lado a otro.

Les voy a mostrar un cuadro que vi hace tiempo en msdn, y que ilustra muy bien las categorías de los miembros de la clase Marshal:



En este artículo utilizaremos principalmente los miembros de la categoría Data transformation, qué son los que nos permiten pasar data del entorno administrado al nativo y viceversa. Como vemos en la tabla, los métodos son bastante descriptivos, por ejemplo StringToHGlobalAnsi lo que hace es copiar el contenido de un string administrado a la memoria nativa, y te retorna la dirección en donde copió la data.

En esta página de msdn Marshal Members podrán ver bien qué hace cada miembro y si requiere de algún paso adicional, como es el caso de StringToHGlobalAnsi, el cual necesita llamar a la función FreeHGlobal (también de Marshal)

Veamos un ejemplo práctico del uso de Marshal:

Un amigo de acá del foro, [Zero], tiene una clase en C, es una especie de utilitario. Para el ejemplo usaremos la siguiente función del código de [Zero]:


//La funcion lo que hace es terminar un proceso en ejecucion.
int cTerminateProcess(char* lpProcessName)
{
HANDLE hProcess=NULL;
HANDLE hSnapshot=NULL;
PROCESSENTRY32 *pInfo=NULL;

hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(!hSnapshot) return -1;

pInfo=(PROCESSENTRY32*)GlobalAlloc(GPTR,sizeof(PROCESSENTRY32));
pInfo->dwSize=sizeof(PROCESSENTRY32);

//Obtenemos el PID del proceso
Process32First(hSnapshot,pInfo);
do
{
if(!lstrcmpA(pInfo->szExeFile,lpProcessName))
{
if(OpenProcess(PROCESS_TERMINATE,FALSE,pInfo->th32ProcessID))
{
hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,pInfo->th32ProcessID);
}
}
}while(Process32Next(hSnapshot,pInfo));

GlobalFree(pInfo);

if(!hProcess) return -1;

if(!TerminateProcess(hProcess,0))return -1;

Sleep(100);

return 1;
}



Supongamos que yo quiero usarlo desde .Net, ¿Cómo sería eso posible? No es muy dificil, ni requiere mucho tiempo. La idea es crear una librería en .Net la cual podamos referencia sin ningún problema, esto se llama wrapper, y lo haremos desde C++ CLI, el cual nos permite exactamente lo que queremos, interactuar entre entornos Administrados y Nativos mucho más fácil que desde C#, aunque sigue siendo posible, pero tendríamos que usar el keyword unsafe. En C++ tenemos mucho más fácil el acceso a la memoria nativa del sistema, y el mismo acceso al framework.

Ahora sigamos los siguientes pasos para crear nuestro Wrapper:

1.- Creamos una Solución en Blanco en Visual Studio
Le ponen un nombre y click en aceptar. Eso es todo.!

2.- Ahora agregamos Un Proyecto C++ (Static Library)
Este proyecto es donde va el código en C, es decir, las funciones a las cuales les queremos hacer el wrapper (en español es algo como envoltorio, ya veremos por qué). Para crear el proyecto le dan botón derecho en la solución, en el explorador de soluciones. Luego Agregar Nuevo Proyecto. En la ventana seleccionen Visual C++ y en el listado escojan Win32 Project, le dan un nombre y Click en Aceptar.

Aquí es donde va la función cTerminateProcess del código de [Zero].

3.- Creamos un Proyecto C++ CLI (Dynamic Library)
Este va a ser nuestro Wrapper, por lo que crearemos un proyecto en C++ CLI de tipo Dynamic Library, es decir una DLL. De la misma forma que con el proyecto anterior, agregamos un nuevo proyecto seleccionamos igual Visual C++ pero esta vez el tipo de Proyecto será Class Library. Nombramos el proyecto y aceptamos.

Ahora tenemos que hacer dos cosas, la primera es agregar el directorio en donde está el .h del proyecto de C, esto se hace yendo a las propiedades del proyecto > Propiedades de Configuración > C/C++ > General, y dónde dice Additional Include Directories agregar el directorio correspondiente. El segundo paso es agregar a la lista de dependencias la dirección en donde está el .lib que es el resultado del static library en C. Pueden hacerlo yendo a Propiedades de Configuración > Linker > Input, agregandolo en donde dice Dependencias Adicionales.

Ya tenemos todo listo para comenzar a hacer el wrapper.

Creamos una clase y le ponemos el nombre que quieras ponerle cuando la vayan a utilizar, por lo que debe ser un nombre que haga referencia a la función del código. En nuestro caso le pondremos DemoClass. Se crearán dos archivos uno .h y otro .cpp, Abrimos el .h para definir la clase y el método que queremos.

El código del .h quedaría así:
Código (cpp) [Seleccionar]

// DemoClass.h

#pragma once

using namespace System;

namespace Demo{

public ref class DemoClass
{
public:
int TerminateProcess(String^ ProcessName);
};
}


Si recordamos la función en C se llama cTerminateProcess, entonces en nuestro wrapper se llamará simplemente TerminateProcess, los parámetros es algo que hay que tener en cuenta, la funcion original pide char*, en .Net la idea es NO usar punteros por lo que usaremos String, y vale la pena recalcar el uso del simbolo ^ que es simplemente para identificar las referencias a código administrado y código nativo.

Ya tenemos el .h listo, vamos a codificar el cpp:

Código (csharp) [Seleccionar]

// This is the main DLL file.

#include "stdafx.h"
#include <vcclr.h>
#include "DemoClass.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace Demo{
       int DemoClass::TerminateProcess(String^ ProcessName)
{
               //Validamos :)
if(!ProcessName)
throw gcnew ArgumentNullException;

               //Utilizamos StringToHGlobalAnsi el cual pide String como parametro
               //como retorna un puntero, y sabemos que es un string, le hacemos un
               //cast a char*
char* lpProcessName = (char*)(void*)Marshal::StringToHGlobalAnsi(ProcessName);

               //ejecutamos cTerminateProcess y le pasamos lpProcessName
int result = AmC::cTerminateProcess(lpProcessName);

               //liberamos la memoria usada por lpProcessName , y retornamos
Marshal::FreeHGlobal((System::IntPtr)(void*)lpProcessName);
return result;
}
}


Como pueden ver no es nada complicado, aunque hay que hacerlo muy bien para no dejar punteros sin liberar ni funciones sin validar.


3.- Por último agregamos un Proyecto C# en Windows
Usaremos el proyecto para testear la libería. Al Form1 le agregamos un botón y un textbox.

Doble Click al botón para subscribirnos al evento Click, y colocamos esto:

Código (csharp) [Seleccionar]

DemoClass m_amNet = new DemoClass();
m_amNet.TerminateProcess(m_terminateProcessTextBox.Text);


Simplemente creamos una instancia de la clase DemoClass y llamamos al método TerminateProcess que a su vez llama al cTerminateProcess en la liberia en C.

Presionamos F5 para compilar y ejecutar nuestra solución, ejecutamos la calculadora, colocamos ese nombre calc.exe (el nombre del proceso de la calculadora) en el textbox, por último hacemos click en el botón y si todo sale bien debería cerrarse el proceso.



Espero les sirva de ayuda, si hay algún error me avisas y lo corregimos.

Un saludo!
#1002
Puedes aclarar un poco tu pregunta, que no la entiendo.

Saludos!
#1005
.NET (C#, VB.NET, ASP) / Re: C# y Crystal
3 Agosto 2010, 14:43 PM
Esas son las malas costumbres que vienen de FoxPro xD

Vale, espero que con ese filtro que le pusiste te haya ido mejor, cualquier cosa avisa.

Saludos!
#1006
No se si el TabControl te esté ralentizando, pero en caso de que así sea, crea tu propio control. Y olvidate de las opciones en tiempo de diseño, haces todo a código, de esa forma va a ir mucho más rápido. Creo. :P
#1007
Bueno, puedes buscar uno en codeproject, o te puedes hacer tu propio control, es un poco tedioso pero nada imposible. Si no tienes mucha práctica búsca en codeproject debe haber algo interesante ahí..

saludos!
#1008
Cita de: do-while en  2 Agosto 2010, 22:26 PM
Cierto, ahi esta la diferencia entre analisis y algebra. Algebraicamente no se puede dividir por cero, pero en analisis realmente no estas haciendo una division por cero, sino que estas viendo como varia la proporcion entre numerador y denominador.  Ambas respuestas tienen su sentido segun de que se hable, si de algebra o de analisis.

Por otra parte, si cualquier cosa es posible, es posible que todo sea posible, por lo que es posible que todo sea imposible, y tenemos una contradiccion, es decir, no cualquier cosa es posible y por lo tanto tiene que existir al menos una cosa que sea imposible.

¡Saludos!

Uhmmmm   :o :o :o
#1009
A continuación un listado de lost post que se han creado en este subforo, para que de esta forma no sean olvidados y podamos accesarlos fácilmente. También le doy las gracias a Raul338 por ayudarme, ya que el revisó la mitad y yo la otra mitad de los posts  :D (Aunque al final terminó revisando más páginas que yo hehe)


Definiciones y conceptos:
F.A.Q. - Frequently Asked Questions Autor: Mace Windu
Conceptos de la arquitectura .NET Framework Autor: Mace Windu
[Enlace] Diferencias de sintaxis entre VB y C# Autor D4N93R


Tutoriales .Net:
Sockets en C# Autor Hendrix
Tutorial API Google Maps con VB. NET y C# Autor: seba123neo (Post en Construcción)
Delegados C# Autor D4N93R
Exportar DataGridView a Excel, PDF y HTML Autor oscarj24
Tcp/IP Sockets C# Autor D4N93R
CLR Stored Procedures (Sql Server) Autor: D4N93R
Desarrollo de juegos en Windows Phone 7 usando XNA Autor: D4N93R (Post en Construcción)
Algunos Trucos VB Autor: Keyen Night
Introducción a System.Reflection Autor: D4N93R
Nuevas Características de C# en .Net 4.0  Autor: D4N93R
[Descarga] Manual C# Autor del post DaNuK, Autor del libro: ?
¿System.Threading? ¡Cómo y Cuándo! (C#) Autor: D4N93R
Marshal - Interactuando entre managed y unmanaged memory. (C++ CLI) Autor: D4N93R
Tutorial Skechflow - expression Studio Autor: cbug
Introducción al crackeo manual de aplicaciones .NET Autor: 43H4FH44H45H4CH49H56H45H
[APORTE] Cómo utilizar las clases HttpWebRequest y HttpWebResponse Autor: .:Weeds:.
[TUTORIAL] Instalar controles de terceros en VS2012 desde la consola de Windows. Autor: EleKtro
[WPF][ESP] Manual - +350 pgs Autor: NullPointerEx
[C#] Creacion de un Keylogger Autor: Doddy


IDES, Librerías, Plantillas, Controles de usuario, Heramientas externas, Addons en general :
VisualStudio 2013 Elektro Ultimate Pack (Instalador+Plantillas+Snippets+Libs+Controles+Tools)  Autor: EleKtro
Librería de Plantillas  Autor: EleKtro
[Tutorial] Skins para C# Autor: Doddy
[APORTE] Amazing ProgressBar Autor: EleKtro


Aplicaciones y códigos fuente:
[APORTE] Usando consola con Threads (aka: consola estilo quake) Autor: raul338
Bloc de Notas V2.0 Autor: Braayhaan
Clase para conversiones de sistemas numericos Autor: Kalith
Formulario dentro de otro Formulario???? C# Autor: Hartigan
Keylogger 2.0 Autor: BlazeFire
Mailsender [c# + expression blend] Autor: siddexter
Source Firma Digital C# 2010 Autor: N3FISTO
[SOURCE-C#] Bot Flogger (+ InputBox para C#) Autor: raul338
Twitter App
Users Profile v1.0 (para ver los perfiles de usuario de elhacker.net) Autor: seba123neo
Visual Studio 2010 Express - Descargas e Info
AutoRemoveX + SourceCode Autor: WHK
[C#] Compilador de arhivos batch a exe Autor: neoncyber
Clase ODP.net Oracle Data Provider C# Autor: cyberserver
Nickmania sourcecode Autor: WHK
Aplicación para ver los usuarios Online en el foro Autor: seba123neo
Buscador de Mercadolibre (Todos los Paises) Autor: seba123neo
[APORTE] Plantillas de Game Launchers para juegos de Steam Autor: EleKtro
PlayDir 2.0 Autor: EleKtro
Splitty Autor: EleKtro
AeroSwitch Autor: EleKtro
Color.NET Autor: EleKtro
CopyInfo Autor: EleKtro
CTool Autor: EleKtro
DoCrypt Autor: EleKtro
FileDate Autor: EleKtro
MouseLock CLI Autor: EleKtro
MouseLock (GUI version) Autor: EleKtro
MP3Crank Leecher Autor: EleKtro
PATHS Autor: EleKtro
Plixid Leecher Autor: EleKtro
Post-Hardcore.ru Leecher Autor: EleKtro
REG2BAT Autor: EleKtro
RegEx.NET Autor: EleKtro
RegOpen Autor: EleKtro
RepairShortcuts Autor: EleKtro
SEO Calculator Autor: EleKtro e IkillNukes
Splat Autor: EleKtro
Volium Autor: EleKtro
Mouse XY Autor: EleKtro
Text Affixer Autor: EleKtro
ASCII Format Autor: TMarmol
Advanced Cloc: Lector de líneas de código   Autor: Ikillnukes
mrtzcmp3 Downloader Autor: Ikillnukes
[C#] VirusTotal Scanner 0.1 Autor: Doddy
[C#] LocateIP 0.2 Autor: Doddy
[C#] MD5 Cracker 0.3 Autor: Doddy
[C#] SQLI Scanner 0.4 Autor: Doddy
[C#] HTTP FingerPrinting 0.2 Autor: Doddy
[C#] PanelFinder 0.3 Autor: Doddy
[C#] K0bra 1.0 Autor: Doddy
[SOURCE] Elektro ErrorDialog Autor: EleKtro
[SOURCE] Elektro RadErrorDialog Autor: EleKtro


Snippets (porciones de código reutilizables):
Librería de Snippets !! (Compartan aquí sus snippets)  Autor: EleKtro


Micelaneos:
Como abrir tu aplicacion .NET sin .NET Framework instalado Autor Rakzo-Fimbres
.NET Code Converter: C# or VB –to-> C#, VB, Python or Ruby Autor: nicolas_cof
Retos en .Net
[Guia] Compilando Mono
Mejora la seguridad de tu aplicacion .Net Autor: .:Weeds:.
[APORTE] Convierte código entre C++, C#, Java y VB.NET Autor: EleKtro


Temas solucionados con contenido interesante
Guardar Imagen en base de datos. (c#) Autor Hartigan
Como puedo conseguir abrir una ventana de MS-DOS dentro de Formulario Autor: 777Rubenix777
[C#] Identificar cuando una aplicación externa es cerrada Autor HappyNewYear
Usuarios conectados a un servidor o pc Autor: darnali
Crear un sistema de plug-Ings y scripts en mi aplicacion Autor: Zeroql
problemas con C# y wiimote Autor: usb.n
Puedo vender mi aplicacion hecha con .NET ? Autor: nico56
[C#] abrir archivos mediante Drag Drop Autor: SRVAM
Cifrando y Descifrando C# Autor: junxcosio


Si me faltó algo, o desean que agregue algún post en especial, me envían un MP con el enlace. De esta forma mantenemos este hilo limpio :)
#1010
.NET (C#, VB.NET, ASP) / Re: C# y Crystal
2 Agosto 2010, 17:21 PM
Quién va a leer un reporte con más de 10.000 registros?  :-\