'Trying to reverse ObjPtr to an Object I'm getting kernel not found error 53 in 64 bits but not in 32 bits

I'm referring Parent class from Child class; instead of simply do, for example:

Public Property Set Parent(obj As ClassProperties)
    Set this.ParentColl = obj
End Property

I rather prefer to avoid references to and from getting entangled and 'out of memory' error when I loop through and create instances of the class so I use this that is based on that.

It functions as a charm in 32 bits but at 64 bits I'm getting Runtime error '53' File not found: kernel.

In a module:

#If VBA7 Then
    Private Declare PtrSafe Sub CopyMemory Lib "kernel" Alias "RtlMoveMemory" _
     (dest As Any, Source As Any, ByVal Length As LongPtr)
#Else
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
     (dest As Any, Source As Any, ByVal Length As Long)
#End If

'Returns an object given its pointer.
Public Function ObjFromPtr(ByVal pObj As Long) As Object
    Dim obj As Object
    CopyMemory obj, pObj, 4
    Set ObjFromPtr = obj
    CopyMemory obj, 0&, 4
End Function

Public Function ObjFromPtrVBA7(ByVal pObj As LongPtr) As Object
    Dim obj As Object
    CopyMemory obj, pObj, 4  <== here is the error
    Set ObjFromPtrVBA7 = obj
    CopyMemory obj, 0&, 4
End Function

At Child class:

    #If VBA7 Then 'Uses modParentChildDereference
    Private mlParentPtr As LongPtr
    #Else
    Private mlParentPtr As Long
    #End If
Public Property Get Parent() As ClassProperties 
    #If VBA7 Then 'Uses modParentChildDereference
    Set Parent = modParentChildDereference.ObjFromPtrVBA7(mlParentPtr)
    #Else
    Set Parent = modParentChildDereference.ObjFromPtr(mlParentPtr)
    #End If
End Property
Public Property Set Parent(obj As ClassProperties)
    mlParentPtr = ObjPtr(obj)
End Property

At Parent Class:

    Set newItem.Parent = Me

At CopyMemory obj, pObj, 4 I can see the LongPtr, like 1234567789^, but CopyMemory is unable to find the Obj at kernel.

I read some deep threads over CopyMemory here and here.

Based on those I played a little with CopyMemory obj, pObj, 4 and gave it different numbers, like 8 and 16 but to no avail.

Any directions or solutions? TIA



Solution 1:[1]

The link provided by @UnhandledException in the comment above directed me to an amazing thread

I implemented it, adapting to 64 bits - see my answer there - and got a totally different kind of errors, even crashing VBE, video driver and windows.

But one comment at OP opened my eyes:

Please don't hard-code the size... ever. LenB is to VBA what sizeof is to C. Use it to size the allocation for the copy memory API. – this

Back to work:

Public Function ObjFromPtr(ByVal pObj As Long) As Object
    Dim obj As Object
    CopyMemory obj, pObj, LenB(obj) 'not size 4!
    Set ObjFromPtr = obj
    CopyMemory obj, 0&, LenB(obj) 'not size 4!
End Function

Public Function ObjFromPtrVBA7(ByVal pObj As LongPtr) As Object
    Dim obj As Object
    CopyMemory obj, pObj, LenB(obj) 'not size 4!  <== here the error no more!!!!
    Set ObjFromPtrVBA7 = obj
    CopyMemory obj, 0&, LenB(obj) 'not size 4!
End Function

So, answered.

Thanks a lot community!

Solution 2:[2]

Even on a 64-bit Windows and 64-bit Office (VBA), the kernel dll is still "kernel32"! Thats what "Runtime error '53' File not found: kernel." clearly sayd.

In fact, all 64bit system libraries are located under %SystemRoot%\System32 whereas the same libraries for 32bit subsystems are in %SystemRoot%\SysWOW64. (Yes, thats right, even when the naming suggest the reverse)

So

#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
     (dest As Any, Source As Any, ByVal Length As LongPtr)
#End If

works for both, Office32 and Office64 systems as long as they already use the VBA7 engine.

But Marcelo is also right, LenB(pObj) (pObj or any LongPtr variable) should be used as length parameter. But LenB(obj), as suggested by Marcelo, doesnt work for me (Office2013) because obj is Nothing and LenB tries to derefer the obj instance.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcelo Scofano Diniz
Solution 2 Merilix2