如何检测传入方法的数组是变量数组还是字面量数组?
场景示例
变量传递数组
Dim myA as Variant myA = Array(1,2,3,4,5) myMethod myA
字面量直接传递数组
myMethod Array(1,2,3,4,5)
当前困境
已检查Variant的VT类型(两种情况均为&H0880)和SafeArray结构体的fFeatures标志(均为&H200C),无法通过这两个字段区分数组类型。
背景需求
需实现一个持久化数组引用的类:变量数组可直接持有引用,而字面量数组是临时对象,方法返回后即失效,必须复制其内容才能持久化。
后续排查方向
追踪数组引用计数
字面量临时数组的初始引用计数通常为1(无其他变量持有),而变量数组的引用计数至少为2(变量本身+方法参数引用)。可通过ObjPtr结合Windows API(如IUnknown接口的AddRef/Release)间接判断引用计数,注意操作时的内存安全。检查内存分配区域
字面量数组多分配在临时栈或临时堆区域,变量数组则通常在进程堆中。通过VarPtr获取数组内存地址,调用Windows API判断该内存区域的属性(如是否为栈内存、是否属于临时分配块),以此区分两类数组。验证数组生命周期
在类中保存数组的内存指针,在方法返回后尝试间接访问该指针(需做好异常捕获):若触发内存访问错误,说明是临时字面量数组;若能正常访问,则为变量数组。深挖SafeArray结构体细节
除fFeatures外,检查SafeArray的其他字段:比如cLocks(临时数组的锁计数可能为0)、pvData指向内存的分配属性,或解析fFeatures的每一位标志是否存在细微差异(可能之前的位解析不完整)。备选规避方案
若排查困难,可强制调用方将数组赋值给变量后再传递,或在方法内部默认复制所有传入数组的内容,无需区分类型(牺牲部分性能换稳定性)。
内容的提问来源于stack exchange,提问作者freeflow

