Autor
|
Tema: Error CopyMemory y estructura SafeArray (Via API) (Leído 4,346 veces)
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
Edito: Antes que nada No es factible hacer un Simple Copymemory por que Crashea!¡ de forma instantanea asi que para esto hay que manipular y bloquear el Array con la estructura SafeArray.Pero aun no encuentro la Solución [/i][/b] intento copiar el contenido de una variable tipo variant a una avriable de matrix variant Dim VarVariant as variant
a Dim VarVariantDest() as variant
La cosa es sencilla, copia bien la primera vez posteiormente me crashea... y creo que es por la Estructura SafeArray, ( ya intente varias cosas incluida sin Apis y con solo manejo de la dicha Estructura y sigue de la misma manera!¡. ) Aqui el codigo Option Explicit Option Base 0 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function SafeArrayAccessData Lib "Oleaut32" _ (ByVal psa As Long, pvData As Long) As Long Private Declare Function SafeArrayUnaccessData Lib "Oleaut32" _ (ByVal psa As Long) As Long ' // msvbvm60.DLL Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" _ (Var() As Any) As Long Private Sub Test_Translate() Dim VarVariant As Variant Dim VarVariantDest() As Variant Dim aaa(0 To 3) As Variant Dim psa As Long Dim pData As Long aaa(0) = "Miguel" aaa(1) = "Angel" aaa(2) = "Ortega" aaa(3) = "Avila" VarVariant = aaa ReDim Preserve VarVariantDest(0 To 7) CopyMemory psa, ByVal VarPtr(VarVariant)+8, 4 If SafeArrayAccessData(psa, pData) = 0 Then ' Bloqueo el Array y obtengo el puntero de varptr(VarVariant(0)) CopyMemory VarVariantDest(4), ByVal pData, 4 * 16 ' Copio el Contenido SafeArrayUnaccessData psa ' Desbloqueo el array End If For psa = LBound(VarVariantDest) To UBound(VarVariantDest) Debug.Print psa, VarVariantDest(psa) Next psa End Sub Private Sub Form_Load() Dim i As Byte For i = 1 To 10 Call Test_Translate MsgBox "Prueba: " & i Next i End Sub
Dulces Infierno Lunar!¡.
|
|
« Última modificación: 24 Agosto 2010, 03:18 am por BlackZeroX »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
solo como dato para no matarse , la estructura SafeArray es de 16 Bytes aqui se las dejo por si alguien la requiere con esta cuestion!¡. Private Type SafeArrayReader cDims As Integer ' nr of dimensions for the array fFeatures As Integer ' extra information about the array contents cbElements As Long ' nr of bytes per array element. Possible Examples: 1=byte,2=integer,4=long,8=currency cLocks As Long ' nr of times array was locked w/o being unlocked pvData As Long ' address to 1st array item, can be a pointer to another structure/address End Type
Nota: Solo Array's, aun queen este caso... Dulces Lunas!¡.
|
|
« Última modificación: 24 Agosto 2010, 03:07 am por BlackZeroX »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
Tokes
Desconectado
Mensajes: 140
|
Oye, BlackZeroX, no entiendo algo (por no decir todo): ¿La variable psa que papel juega ahí? ¿Si la usamos en copymemory que es lo que hace? Si ejecuto tu código como está se cierra visual basic. Si lo ejecuto así, ya no se cierra: If SafeArrayAccessData(VarPtr(VarVariant), pData) = 0 Then aunque, claro, no tengo ni la menor idea de que es lo que hace. Saludos.
|
|
|
En línea
|
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
PSA es el puntero a la estructura SafeArray es decir hay algo que no saben muchos y es que una variable es una estructura... pero en este caso PSA son los 4 primeros bytes a esta ( SAFEARRAY) la cual contiene informacion de la variable, si es una variable Variant sin matrix los 4 primeros bytes indican el tipo del mismo los siguientes estas vacios y los 4 siguientes indican el puntero al contenido (en este caso seria asi, si fuese un array la estructura que puse arribita es la usada para saber TODA la informacion de una variable tipo Array, Dimenciones, cuanto pesa una dimencion y por ende la lontitud en bytes del array, el incice inferior, el tipo Gral del Array)!¡. aqui hay un link a la MSDN http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.ole.interop.safearray.aspxEdito:--------------------------> If SafeArrayAccessData(VarPtr(VarVariant), pData) = 0 Then
Esta mal debes pasarle el puntero del SafeArray mas no el de la Variable, SafeArrayAccessData = 0 cuando sale todo bien cualquier otro valor es un Error. Dulces Lunas!¡.
|
|
« Última modificación: 24 Agosto 2010, 03:26 am por BlackZeroX »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
LeandroA
|
hola BlackZerox lo que pusite en este link me funciona bien no entiendo cual es el problema. Saludos.
|
|
|
En línea
|
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
Ok bien el problema es el siguiente en aquel es de esta forma VarVariantOri() -> VarVariantDest()el problema aqui y ahora es VarVariantOri() -> VarVariantAux - VarVariantDest()Los codigos aunque se parecen, realmente SON DISTINTOS!¡. Si pruebas el codigo de arriba veras que te va a Crashear, el otro no te crasheara por que ya esta bien!¡. Dulces Lunas!¡.
|
|
« Última modificación: 24 Agosto 2010, 05:43 am por BlackZeroX »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
Karcrack
Desconectado
Mensajes: 2.416
Se siente observado ¬¬'
|
Antes de ponerme a codear nada... Tu lo que quieres hacer es establecer un nuevo Array tipo Variant en el que el primer valor sea aaa? MOD:http://www.vbforums.com/showthread.php?t=625615 Psyke tiene un primo Ingles!!!
|
|
« Última modificación: 24 Agosto 2010, 11:35 am por Karcrack »
|
En línea
|
|
|
|
|
Psyke1
Wiki
Desconectado
Mensajes: 1.089
|
Esta es la respuesta que me han dado traducida con Google ( no os riais ): Crashea porque los artículos VarVariantDest de 4, 5, 6 y 7 contienen los punteros a los datos exactamente la misma cadena que está contenido por la AAA.
Al final del procedimiento Test_Translate, cuando se limpia las cosas, dicen que primero destruye aaa y todas las cadenas contenidas en él. A continuación se limpia VarVariantDest - pero contiene punteros a las cadenas que ya han sido destruidos. Resultado final: usted obtiene un accidente.
En este caso es mucho mejor usar la antigua forma para copiar el contenido de la matriz, especialmente si usted no está tratando de lograr la eliminación de los elementos de la matriz original y simplemente colocando el directamente en la matriz de otros. ¿No sabe cómo está familiarizado con el almacenamiento de cadenas / referencias. Una cadena almacenada dentro de nada: matriz variante, o, simplemente, una variable de cadena en realidad no contienen los datos de cadena. Los datos de cadena se almacena en otra parte de la memoria. variable de cadena: la variable contiene una cadena de bytes puntero del 4 al carácter primero de los datos de la cadena matriz de cadenas dinámica: la matriz se compone de 4 entradas de bytes. Cada entrada de la matriz es un puntero de cadena variante: los datos dentro de la variante es un puntero de cadena Cada vez que un puntero de cadena se copia con CopyMemory, va a copiar el puntero, no la cadena. Cuando una cadena se copia con VB (es decir, newString oldString =), una nueva cadena se crea y cada variable tiene un puntero distinto. Si un puntero se duplica con cada vez CopyMemory, una copia de ese puntero debe ser llevado a cero otra cosa que obtener accidentes. Como Merri explicó esto se debe a VB limpia las cuerdas y que está tratando de limpiar la misma cadena dos veces. La primera vez que está bien, la memoria por segunda vez ya no se asigna y se bloquea la aplicación. Mira esto: http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495Fuente: http://www.vbforums.com/showthread.php?p=3870342#post3870342 DoEvents¡!
|
|
« Última modificación: 24 Agosto 2010, 19:06 pm por *PsYkE1* »
|
En línea
|
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
. mmm como dato es cuando se consultan los valores de VarVariantDest despues de haber hecho el CopyMemory (en el For Next), bueno mejor dicho el Crash no se presenta al final del proceso se Produce en la Consulta
La solucion que estoy viendo es obtener el puntero a la matriz aaa() por medio de VarVariant, haber si lo calculo, ya les cuento!¡.
Dulces Lunas!¡.
|
|
« Última modificación: 24 Agosto 2010, 19:00 pm por BlackZeroX »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[Ayuda] Sobre copyMemory
Programación Visual Basic
|
ignorantev1.1
|
0
|
1,820
|
24 Febrero 2011, 22:37 pm
por ignorantev1.1
|
|
|
error estructura al compilar
Programación C/C++
|
indict
|
4
|
2,412
|
2 Julio 2013, 18:39 pm
por indict
|
|
|
Error:Estructura con strings
Programación C/C++
|
SkaTrumpet
|
2
|
2,163
|
12 Mayo 2016, 14:52 pm
por AlbertoBSD
|
|
|
Error que no encuentro (C - Estructura, vectores)
Programación C/C++
|
Geg1
|
7
|
2,449
|
16 Noviembre 2016, 01:23 am
por engel lex
|
|
|
Error en la estructura in_addr
Programación C/C++
|
mester
|
1
|
1,538
|
23 Marzo 2017, 17:22 pm
por xv0
|
|