尝试将 ObjPtr 反转为 Object 我发现 64 位内核未找到错误 53,但 32 位不是
Trying to reverse ObjPtr to an Object I'm getting kernel not found error 53 in 64 bits but not in 32 bits
我指的是 Parent class 来自 Child class;而不是简单地做,for :
Public Property Set Parent(obj As ClassProperties)
Set this.ParentColl = obj
End Property
我宁愿避免在循环和创建 class 的实例时出现纠缠不清的引用和 'out of memory' 错误,所以我使用 this that is based on that.
它在 32 位中起到了很好的作用,但在 64 位中我得到了运行时错误“53”未找到文件:内核。
在一个模块中:
#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
在 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
在 Parent Class:
Set newItem.Parent = Me
在CopyMemory obj, pObj, 4 我可以看到LongPtr,比如1234567789^,但是CopyMemory 无法在内核找到Obj。
我在 CopyMemory here and here 上阅读了一些深度线程 here and here。
基于这些,我玩了一些 CopyMemory obj、pObj、4 并给了它不同的数字,例如 8 和 16,但无济于事。
有什么指导或解决方法吗?
TIA
@UnhandledException 在上面的评论中提供的 link 将我引导至 amazing thread
我实现了它,适应 64 位 - see my answer there - 并得到了完全不同类型的错误,甚至崩溃了 VBE、视频驱动程序和 windows。
但是 OP 上的一条评论让我大开眼界:
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
恢复工作:
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
所以,回答。
非常感谢社区!
即使在 64 位 Windows 和 64 位 Office (VBA) 上,内核 dll 仍然是“kernel32”!
这就是“未找到运行时错误‘53’文件:内核”。说的很清楚。
事实上,所有 64 位系统库都位于 %SystemRoot%\System32
下,而 32 位子系统的相同库位于 %SystemRoot%\SysWOW64
下。
(是的,没错,即使命名建议相反)
所以
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(dest As Any, Source As Any, ByVal Length As LongPtr)
#End If
适用于 Office32 和 Office64 系统,只要它们已经使用 VBA7 引擎。
但 Marcelo 也是对的,LenB(pObj)
(pObj 或任何 LongPtr 变量)应该用作长度参数。但正如 Marcelo 所建议的,LenB(obj) 对我(Office2013)不起作用,因为 obj 是 Nothing 并且 LenB 试图取消引用 obj 实例。
我指的是 Parent class 来自 Child class;而不是简单地做,for
Public Property Set Parent(obj As ClassProperties)
Set this.ParentColl = obj
End Property
我宁愿避免在循环和创建 class 的实例时出现纠缠不清的引用和 'out of memory' 错误,所以我使用 this that is based on that.
它在 32 位中起到了很好的作用,但在 64 位中我得到了运行时错误“53”未找到文件:内核。
在一个模块中:
#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
在 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
在 Parent Class:
Set newItem.Parent = Me
在CopyMemory obj, pObj, 4 我可以看到LongPtr,比如1234567789^,但是CopyMemory 无法在内核找到Obj。
我在 CopyMemory here and here 上阅读了一些深度线程 here and here。
基于这些,我玩了一些 CopyMemory obj、pObj、4 并给了它不同的数字,例如 8 和 16,但无济于事。
有什么指导或解决方法吗? TIA
@UnhandledException 在上面的评论中提供的 link 将我引导至 amazing thread
我实现了它,适应 64 位 - see my answer there - 并得到了完全不同类型的错误,甚至崩溃了 VBE、视频驱动程序和 windows。
但是 OP 上的一条评论让我大开眼界:
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
恢复工作:
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
所以,回答。
非常感谢社区!
即使在 64 位 Windows 和 64 位 Office (VBA) 上,内核 dll 仍然是“kernel32”! 这就是“未找到运行时错误‘53’文件:内核”。说的很清楚。
事实上,所有 64 位系统库都位于 %SystemRoot%\System32
下,而 32 位子系统的相同库位于 %SystemRoot%\SysWOW64
下。
(是的,没错,即使命名建议相反)
所以
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(dest As Any, Source As Any, ByVal Length As LongPtr)
#End If
适用于 Office32 和 Office64 系统,只要它们已经使用 VBA7 引擎。
但 Marcelo 也是对的,LenB(pObj)
(pObj 或任何 LongPtr 变量)应该用作长度参数。但正如 Marcelo 所建议的,LenB(obj) 对我(Office2013)不起作用,因为 obj 是 Nothing 并且 LenB 试图取消引用 obj 实例。