Tema destacado: Recuperar cuenta de Google, GMail, Youtube
Autor
|
Tema: Dudas trabajando con memoria VB (Leído 1,070 veces)
|
RHL
Conectado
Mensajes: 968
mental
|
 pues si estoy aprendiendo a usar la memoria  pero ya tengo bastantes dudas bueno tengo un codigo: Private Type AAA A1 As Integer A2 As Integer A3 As Long A4 As String End Type Private Sub Form_Load() Dim A0 As AAA Dim dir As Long A0.A2 = 20 dir = VarPtr(A0) dir = dir + 2 Debug.Print dir End Sub pues segun lo que e aprendido es una estructura los valores se almacenan en la memoria consecutivamente osea que en esa estructura los valores deberian estar asi: AAA A1 A2 A3 A4 |XXXX|XXXX|XXXXXXX|XX|
sino e aprendido mal la variable interger son 2 bytes, un long son 4 bytes , un string ( en esta no se si estoy en lo corecto  seguramente no ) son 2 bytes bueno pues con la funcion varptr obtengo la direccion de la memoria del primer byte de la estructura y comprobar que los datos se almacenan en forma consecutiva quiero obtener el valor de A2 que por eso le asigne el valor de 20 bueno panas creo que ya saben viendo mi codigo que quiero comprobar que quiero aprender y exactamente quiero mostrar el valor 20 ya que segun yo tengo la direccion de memoria . Gracias 
|
|
|
|
« Última modificación: 3 Agosto 2011, 23:38 por raul338 »
|
En línea
|
|
|
|
|
raul338
|
un string ( en esta no se si estoy en lo corecto  seguramente no ) son 2 bytes Un string son 2 * caracteres + 2 bytes. Estas usando bien el VarPtr pero no con el Debug.Print porque la variable dir es un Puntero y necesitas leer 2 bytes (que es el tamaño del proximo Integer) y para eso necesitas la api RtlMoveMemory o conocida socialmente como CopyMemory 
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
 gracias raul338 ahora comprendo porq la tan famosa copymemory que es con la que se trabaja con la memoria en vb dejo mi enigma resuelto  : Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) Private Type AAA A1 As Integer A2 As Integer A3 As Long A4 As String End Type Private Sub Form_Load() Dim A0 As AAA Dim dir As Long Dim destino As Integer A0.A2 = 20 dir = VarPtr(A0) dir = dir + 2 CopyMemory ByVal VarPtr(destino), ByVal dir, LenB(dir) Debug.Print destino End Sub por cierto algo de informacion trabajando con la memoria en vb? busque en el foro y encontre unos tutos pero no me ayudaron mucho  muy avanzado creo 
|
|
|
|
« Última modificación: 4 Agosto 2011, 03:17 por raul338 »
|
En línea
|
|
|
|
|
raul338
|
dir = VarPtr(A0) dir = dir + 2 CopyMemory ByVal VarPtr(destino), ByVal dir, LenB(dir) Error, dir es Long y lo que queres obtener es Integer, por lo que estas leyendo 4 bytes cuando queres 2. Te da bien porque A0.A3 es 0, sino, te daria cualquier fruta  Sobre tutoriales de ese estilo, no conozco, tampoco es que se use demasiado  PD: Acostumbrate a usar [code =vb][/code] aca 
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
Error, dir es Long y lo que queres obtener es Integer, por lo que estas leyendo 4 bytes cuando queres 2. Te da bien porque A0.A3 es 0, sino, te daria cualquier fruta  Sobre tutoriales de ese estilo, no conozco, tampoco es que se use demasiado  PD: Acostumbrate a usar [code =vb][/code] aca  pero... pero si me imprime el numero 20  que es lo que queria para comprobar  y "dir" es solo una direccion  o en que es lo que fallo ?? 
|
|
|
|
« Última modificación: 4 Agosto 2011, 07:18 por Raul100 »
|
En línea
|
|
|
|
|
raul338
|
La llamada debe ser:
CopyMemory ByVal VarPtr(destino), ByVal dir, 2
Porque vos quereres tener A2, que es un Integer de 2 bytes
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
vale ahora tengo mas dudad  e probado con eso y pues ahora que veo no importa el numero de bytes que le escriba en el tercer parametro siempre pasa el resultado  porq? si le agregara mas bytes no estaria accediendo a las demas variables que se encuentran en esa posicion???  hice este code: Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) Private Type AAA A1 As Integer A2 As Integer A3 As Long A4 As String End Type Private Sub Form_Load() Dim A0 As AAA Dim dir As Long Dim DEST_integer As Integer dim DEST_long as long dim DEST_CHAR as string A0.a1 = 50 A0.A2 = 20 A0.A3 = 50000 A0.A4 = "R" dir = VarPtr(A0) dir = dir + XXX CopyMemory ByVal VarPtr(<type DESTINO>), ByVal dir, LEN DE BYTES Debug.Print destino End Sub vale espero que me ayuden no podria estar bien y no resuelvo esto  pues primero esa duda porq escribiendo cualquier longitud en LEN BYTES( tercer parametro ) el numero de bytes que quiero copiar siempre obtengo el resultado correcto y eso esta bien  solo que tengo una duda si agrego mas bytes no estaria dandome una respuesta incorrecta ???  y pues la otra duda  porq los parametros se pasan por valor?  porq no da el resultado correcto pasandolos por referencia  ? gracias
|
|
|
|
|
En línea
|
|
|
|
BlackZeroX (Astaroth)
Wiki
Desconectado
Mensajes: 2.831
I'Love...!¡.
|
El api CopyMemory trabaja con PUNTEROS que es mas rapido, las Referencias usan los punteros al final y ocupan mas Stack ( creo que era este ) y mas espacio en memoria. Ahora si espesificar X cantidad de Byte´s a leer, este debe ser el Minimo de ambos es decir: funcion min( byval lVal1 as long, byval lVal2 as long ) if ( lval1 > lval2 ) min = lval2 else min = lval1 end funcion ... CopyMemory pDest, pSrc, min( DestLen, SrcLen ) // Suponiendo que ya estan declarados los byval en la declaracion API. ... Si se ingresa un valor superior o se escribe en secciones que no pertenecen a X bloque de bytes ya reservados se le llama "Segmentacion de memoria", ya que estas escribiendo en lugares donde NO deberias escribir/leer. supongamos funcion min( byval lVal1 as long, byval lval2 as long ) if ( lval1 > lval2 ) min = lval2 else min = lval1 end funcion dim iInt as integer dim lLong as long '*** CopyMemory varptr(iInt), varptr(lLong), min( lenb(iInt), lenb(lLong) ) '// Correcto '*** CopyMemory varptr(iInt), varptr(lLong), lenb(lLong) ) '// Incorrecto ' // Ocaciona una segmentacion de memoria y por ende u Crash, ya que se intentan copiar 4 bytes en un bloque donde caben solo 2 bytes. '*** 'Alternativas aun mas rapidas: iInt = lLong and &FFFF '//Correcto '*** iInt = lLong and &FFFFFFFF '// Incorrecto
Dulces Lunas!¡.
|
|
|
|
« Última modificación: 4 Agosto 2011, 19:28 por BlackZeroX▓▓▒▒░░ »
|
En línea
|
|
|
|
|
raul338
|
BlackZeroX lo explico mejor que yo, ademas de que me trabe al intentar hacer un ejemplo practico 
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
gracias BlackZeroX y pues si eso me imaginaba que si se queria acceder a la memoria que no deberia me daria error o me daria un resultado incorrecto  pero pero con la funcion copymemory en el tercer parametro lo correcto seria 2 bytes que son el integer pero y entonces seria el numero 2! pero si ingreso digamos 4 , 6 ,8 el resultado el correcto siempre  y no me da error ni valor incorrecto :/
|
|
|
|
« Última modificación: 4 Agosto 2011, 19:36 por raul338 »
|
En línea
|
|
|
|
|
raul338
|
Ya en algun momento te dará error. Lo que pasa es que esto es en pruebas, Si lo haces al manejar mensajes de windows o modificar programas externos, puede fallar 
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
vale mirad  dir = VarPtr(A0) dir = dir + 2 CopyMemory ByVal VarPtr(destino), ByVal dir, 10 Debug.Print destino e puesto 10 bytes y solamente necesito los 2! significa que estuviera accedienco a memoria prohibida de otra variable o mas de otro programa  y lo peor es que me da correcto 
|
|
|
|
|
En línea
|
|
|
|
jaunx
Desconectado
Mensajes: 20
|
te da correcto porque esos 2 bytes te los copia en su sitio, en el espacio que habías reservado al declarar la variable, pero los otros 8 los copias fuera, prueba a copiar 1000 Para escribir en la memoria de otro proceso necesitas usar WriteProcessMemory.
|
|
|
|
|
En línea
|
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
buen analisis amigo! voy a probar podas las posibles valores que pueda y su reaccion gracias 
|
|
|
|
|
En línea
|
|
|
|
BlackZeroX (Astaroth)
Wiki
Desconectado
Mensajes: 2.831
I'Love...!¡.
|
@Raul100
Dim iVal as integer Dim pArray(10) as long
copymemory byval varptr(pArray(0)), byval varptr(iVal), 10 <--- podria ocacionar un crash
Lo que pasa es simple. un programa se carga completamente de manera contigua = como esta en el HD.
Cada funcion esta en bloques...
Una forma en la que lopuedes ver seria:
| Headers y otras cosas.. | Funcion 0 | Funcion 1 | ... |
Por lo tanto cuando corres el codigo anterior SI y SOLO SI "ival" le sigue otra declaracion de variable copia = su contenido, de lo contrario seran instrucciones de la funcion.
Dulces Lunas!¡.
|
|
|
|
|
En línea
|
|
|
|
|
|