paso para macro mac for ejecutar vba macos winapi declare kernel32

para - vba editor for mac



¿Cómo leer/escribir memoria en Mac OS X con VBA? (2)

En Windows, la función declarada RtlMoveMemory proporciona una forma de copiar un bloque de bytes de una dirección a otra:

Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" ( _ ByVal dest As LongPtr, _ ByVal src As LongPtr, _ ByVal size As LongPtr)

¿Cuál es el equivalente en Mac OS X?


Busqué RtlMoveMemory() en msdn.microsoft.com y parece que simplemente copia un número de bytes de una dirección a otra, entregando el caso especial de la superposición de memoria.

El equivalente de Darwin es void* memmove(void *dst, const void *src, size_t len)

La versión primitiva / más rápida es void* memcpy(void *restrict dst, const void *restrict src, size_t n) , que no maneja regiones de memoria superpuestas.

Haga un man memmove por los detalles.


¿Cuál es el equivalente en Mac OS X?

Respuesta corta:

Private Declare PtrSafe Function CopyMemory Lib "libc.dylib" Alias "memmove" _ ( _ ByVal dest As LongPtr _ , ByVal src As LongPtr _ , ByVal size As LongLong _ ) _ As LongPtr

Respuesta larga: Depende;)

El siguiente es un ejemplo completamente desarrollado que usa la compilación condicional * para permitir que funcione en cualquier computadora Mac / Windows / 32 bits / 64 bits. También demuestra las dos formas diferentes de declarar y llamar a la función (por puntero y por variable).

#If Mac Then #If Win64 Then Private Declare PtrSafe Function CopyMemory_byPtr Lib "libc.dylib" Alias "memmove" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As Long) As LongPtr Private Declare PtrSafe Function CopyMemory_byVar Lib "libc.dylib" Alias "memmove" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) As LongPtr #Else Private Declare Function CopyMemory_byPtr Lib "libc.dylib" Alias "memmove" (ByVal dest As Long, ByVal src As Long, ByVal size As Long) As Long Private Declare Function CopyMemory_byVar Lib "libc.dylib" Alias "memmove" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) As Long #End If #ElseIf VBA7 Then #If Win64 Then Private Declare PtrSafe Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As LongLong) Private Declare PtrSafe Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As LongLong) #Else Private Declare PtrSafe Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As Long) Private Declare PtrSafe Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) #End If #Else Private Declare Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, ByVal src As Long, ByVal size As Long) Private Declare Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) #End If Public Sub CopyMemoryTest() Dim abytDest(0 To 11) As Byte Dim abytSrc(0 To 11) As Byte Dim ¡ As Long For ¡ = LBound(abytSrc) To UBound(abytSrc) abytSrc(¡) = AscB("A") + ¡ Next ¡ MsgBox "Dest before copy = #" & ToString(abytDest) & "#" CopyMemory_byVar abytDest(0), abytSrc(0), 4 MsgBox "Dest during copy = #" & ToString(abytDest) & "#" CopyMemory_byPtr VarPtr(abytDest(0)) + 4, VarPtr(abytSrc(0)) + 4, 4 MsgBox "Dest during copy = #" & ToString(abytDest) & "#" CopyMemory_byPtr VarPtr(abytDest(8)), VarPtr(abytSrc(8)), 4 MsgBox "Dest after copy = #" & ToString(abytDest) & "#" End Sub Public Function ToString(ByRef pabytBuffer() As Byte) As String Dim ¡ As Long For ¡ = LBound(pabytBuffer) To UBound(pabytBuffer) ToString = ToString & Chr$(pabytBuffer(¡)) Next ¡ End Function

Explicación:

La versión de Mac de la función CopyMemory devuelve un resultado, mientras que la versión Win no lo hace. (El resultado es el puntero de destino, a menos que ocurra un error. Consulte la referencia de memmove aquí .) Ambas versiones, sin embargo, se pueden usar exactamente de la misma manera, sin corchetes.

Las diferencias de declaración son las siguientes:

  • Mac / Win VBA7 de 64 bits:

    • Use la palabra clave PtrSafe
    • Utilice el tipo Any para todos los parámetros ByRef
    • Utilice el tipo LongPtr para ByVal handle / puntero parameters / return values
    • Utilice el tipo LongLong forma adecuada para otros valores / parámetros de devolución
  • Win VBA7 de 32 bits:

    • Use la palabra clave PtrSafe
    • Utilice el tipo Any para todos los parámetros ByRef
    • Utilice el tipo LongPtr para ByVal handle / puntero parameters / return values
    • Utilice el tipo Long ( no LongLong ) de forma apropiada para otros valores / parámetros de devolución
  • Mac / Win VBA6 de 32 bits:

    • Sin palabra clave PtrSafe
    • Utilice el tipo Any para todos los parámetros ByRef
    • Utilice el tipo Long para ByVal handle / puntero parameters / return values
    • Utilice el tipo Long apropiadamente para otros valores / parámetros de devolución

Advertencias:

  • Probado en Mac Excel 2016 de 64 bits.
  • Probado en Windows Excel 2007 de 32 bits.

    • Parece que Excel 2007 tiene problemas relacionados con la alineación de palabras dobles. En este ejemplo:

      CopyMemory_byVar abytDest(0), abytSrc(0), 4 ''-> ABCD CopyMemory_byVar abytDest(1), abytSrc(1), 8 ''-> ABCDEFGHI

      CopyMemory() omite todas las copias hasta que se alcanza una alineación de palabra doble (3 saltos en este caso), luego continúa copiando desde el 4to byte.

Nota: Si tiene curiosidad acerca de mi convención de nomenclatura variable, se basa en RVBA .

* La forma correcta .