osx - How to read/write memory on Mac OS X with VBA? -


on windows declared function rtlmovememory provides way copy block of bytes 1 address another:

private declare ptrsafe sub rtlmovememory lib "kernel32" ( _                               byval dest longptr, _                               byval src longptr, _                               byval size longptr) 

what equivalent on mac os x ?

what equivalent on mac os x ?

short answer:

private declare ptrsafe function copymemory lib "libc.dylib" alias "memmove" _                                  ( _                                     byval dest longptr _                                   , byval src longptr _                                   , byval size longlong _                                   ) _                         longptr 

long answer: depends ;)


the following fledged example uses conditional compilation* allow work on mac/windows/32-bit/64-bit computer. demonstrates 2 different ways declare , call function (by pointer , variable).

#if mac   #if win64     private declare ptrsafe function copymemory_byptr lib "libc.dylib" alias "memmove" (byval dest longptr, byval src longptr, byval size long) longptr     private declare ptrsafe function copymemory_byvar lib "libc.dylib" alias "memmove" (byref dest any, byref src any, byval size long) longptr   #else     private declare function copymemory_byptr lib "libc.dylib" alias "memmove" (byval dest long, byval src long, byval size long) long     private declare function copymemory_byvar lib "libc.dylib" alias "memmove" (byref dest any, byref src any, byval size long) long   #end if #elseif vba7   #if win64     private declare ptrsafe sub copymemory_byptr lib "kernel32" alias "rtlmovememory" (byval dest longptr, byval src longptr, byval size longlong)     private declare ptrsafe sub copymemory_byvar lib "kernel32" alias "rtlmovememory" (byref dest any, byref src any, byval size longlong)   #else     private declare ptrsafe sub copymemory_byptr lib "kernel32" alias "rtlmovememory" (byval dest longptr, byval src longptr, byval size long)     private declare ptrsafe sub copymemory_byvar lib "kernel32" alias "rtlmovememory" (byref dest any, byref src any, byval size long)   #end if #else   private declare sub copymemory_byptr lib "kernel32" alias "rtlmovememory" (byval dest long, byval src long, byval size long)   private declare sub copymemory_byvar lib "kernel32" alias "rtlmovememory" (byref dest any, byref src any, byval size long) #end if   public sub copymemorytest()    dim abytdest(0 11) byte   dim abytsrc(0 11) byte   dim ¡ long    ¡ = lbound(abytsrc) 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() byte) string   dim ¡ long   ¡ = lbound(pabytbuffer) ubound(pabytbuffer)     tostring = tostring & chr$(pabytbuffer(¡))   next ¡ end function 

explanation:

the mac version of copymemory function returns result whilst win version not. (the result dest pointer, unless error occurred. see memmove reference here.) both versions, however, can used in same way, without brackets.

the declare differences follows:

  • 64-bit mac/win vba7:

    • use ptrsafe keyword
    • use any type all byref parameters
    • use longptr type byval handle/pointer parameters/return values
    • use longlong type appropriately other return values/parameter
  • 32-bit win vba7:

    • use ptrsafe keyword
    • use any type all byref parameters
    • use longptr type byval handle/pointer parameters/return values
    • use long (not longlong) type appropriately other return values/parameter
  • 32-bit mac/win vba6:

    • no ptrsafe keyword
    • use any type all byref parameters
    • use long type byval handle/pointer parameters/return values
    • use long type appropriately other return values/parameter

caveats:

  • tested on mac excel 2016 64-bit.
  • tested on windows excel 2007 32-bit.

    • seems excel 2007 has issues related double word alignment. in example:

      copymemory_byvar abytdest(0), abytsrc(0), 4 '-> abcd copymemory_byvar abytdest(1), abytsrc(1), 8 '-> abcdefghi

      copymemory() skips copying until double word alignment reached (3 skips in case), continues copying 4th byte.


note: if curious variable naming convention, based on rvba.

*the correct way.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -