首页 > 解决方案 > 使用 GetMem 和 VarPtr 绕过 Object 默认值

问题描述

所以我正在为回调对象制作一个时髦的 VBA 类。目前的问题之一是,当从函数的调用方法返回数据时,我必须运行该方法两次,一次确定变量类型,另一次返回变量:

If VarType(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29))) = vbObject Then
  Set CallCallback = Application.Run( _
    Callback("Parent") & "." & Callback("Name"), _
    args(0), args(1), _
    args(2), args(3), _
    args(4), args(5), _
    args(6), args(7), _
    args(8), args(9), _
    args(10), args(11), _
    args(12), args(13), _
    args(14), args(15), _
    args(16), args(17), _
    args(18), args(19), _
    args(20), args(21), _
    args(22), args(23), _
    args(24), args(25), _
    args(26), args(27), _
    args(28), args(29))
Else
  CallCallback = Application.Run( _
    Callback("Parent") & "." & Callback("Name"), _
    args(0), args(1), _
    args(2), args(3), _
    args(4), args(5), _
    args(6), args(7), _
    args(8), args(9), _
    args(10), args(11), _
    args(12), args(13), _
    args(14), args(15), _
    args(16), args(17), _
    args(18), args(19), _
    args(20), args(21), _
    args(22), args(23), _
    args(24), args(25), _
    args(26), args(27), _
    args(28), args(29))
End If

最近我发现我可以通过使用VarPtr然后使用取消引用结果来多次调用 VBA 函数来做到这一点GetMem4

Private Declare Function GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByRef RetVal As Any) As Long
...
Dim vp As LongPtr, vRet as Variant
vp = VarPtr(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29)))
Call GetMem4(vp, vRet)

这个具体的例子不起作用,但我想知道是否有一个明显的原因说明为什么这不起作用?

有任何想法吗?

标签: excelvba

解决方案


我也向 vbforums 提出了这个问题,他们到达那里的速度比 stackoverflow 快得多

解决方案非常简单:

Public Declare Sub VariantCopy Lib "oleaut32.dll" (ByRef pvargDest As Variant, ByRef pvargSrc As Variant)
...
VariantCopy CallCallback, Application.Run( _
  Callback("Parent") & "." & Callback("Name"), _
  args(0), args(1), _
  args(2), args(3), _
  args(4), args(5), _
  args(6), args(7), _
  args(8), args(9), _
  args(10), args(11), _
  args(12), args(13), _
  args(14), args(15), _
  args(16), args(17), _
  args(18), args(19), _
  args(20), args(21), _
  args(22), args(23), _
  args(24), args(25), _
  args(26), args(27), _
  args(28), args(29))

简单的!


推荐阅读