要进一步扩展var 类型的存储位置并探索函数和其他函数SAFEARRAY
到底在做什么,请参见:SafeArrayGetVartype
SafeArray
SafeArrayGetVartype
/* Memory Layout of a SafeArray:
*
* -0x10: start of memory.
* -0x10: GUID for VT_DISPATCH and VT_UNKNOWN safearrays (if FADF_HAVEIID)
* -0x04: DWORD varianttype; (for all others, except VT_RECORD) (if FADF_HAVEVARTYPE)
* -0x4: IRecordInfo* iface; (if FADF_RECORD, for VT_RECORD (can be NULL))
* 0x00: SAFEARRAY,
* 0x10: SAFEARRAYBOUNDS[0...]
*/
对于以下使用 MS Access VBA 7 的整数数组声明,其中地址引用的大小为 8 个字节。
Dim myArray() As Integer
ReDim myArray(9)
SafeArray 结构的内存转储,包括使用 MS Access VBA 7 的先前隐藏的 VT 数据
Pos Address Dec Address Hex Hex
0 (1185248224) (46A573E0) >> 0h
1 (1185248225) (46A573E1) >> 0h
2 (1185248226) (46A573E2) >> 0h
3 (1185248227) (46A573E3) >> 0h
4 (1185248228) (46A573E4) >> 0h
5 (1185248229) (46A573E5) >> 0h
6 (1185248230) (46A573E6) >> 0h
7 (1185248231) (46A573E7) >> 0h
8 (1185248232) (46A573E8) >> 0h
9 (1185248233) (46A573E9) >> 0h
10 (1185248234) (46A573EA) >> 0h
11 (1185248235) (46A573EB) >> 0h
-------------------------------------------------------------------------------------
Hidden DWord for VT when FADF_HAVEVARTYPE = 0x0080
VT = 2 i.e. Integer
12 (1185248236) (46A573EC) >> 2h
13 (1185248237) (46A573ED) >> 0h
14 (1185248238) (46A573EE) >> 0h
15 (1185248239) (46A573EF) >> 0h
-------------------------------------------------------------------------------------
cDims = 1 i.e. One dimensional array
16 (1185248240) (46A573F0) >> 1h
17 (1185248241) (46A573F1) >> 0h
-------------------------------------------------------------------------------------
fFeatures = FADF_HAVEVARTYPE
18 (1185248242) (46A573F2) >> 80h
19 (1185248243) (46A573F3) >> 0h
-------------------------------------------------------------------------------------
cbElements = 2 i.e. element size is 2 bytes
20 (1185248244) (46A573F4) >> 2h
21 (1185248245) (46A573F5) >> 0h
22 (1185248246) (46A573F6) >> 0h
23 (1185248247) (46A573F7) >> 0h
-------------------------------------------------------------------------------------
cLocks
24 (1185248248) (46A573F8) >> 0h
25 (1185248249) (46A573F9) >> 0h
26 (1185248250) (46A573FA) >> 0h
27 (1185248251) (46A573FB) >> 0h
-------------------------------------------------------------------------------------
Padding
28 (1185248252) (46A573FC) >> 0h
29 (1185248253) (46A573FD) >> 0h
30 (1185248254) (46A573FE) >> 0h
31 (1185248255) (46A573FF) >> 0h
-------------------------------------------------------------------------------------
pvData
32 (1185248256) (46A57400) >> 0h
33 (1185248257) (46A57401) >> 97h
34 (1185248258) (46A57402) >> DCh
35 (1185248259) (46A57403) >> 1Bh
36 (1185248260) (46A57404) >> 0h
37 (1185248261) (46A57405) >> 0h
38 (1185248262) (46A57406) >> 0h
39 (1185248263) (46A57407) >> 0h
-------------------------------------------------------------------------------------
rgsabound(0).cElements = 10
40 (1185248264) (46A57408) >> Ah
41 (1185248265) (46A57409) >> 0h
42 (1185248266) (46A5740A) >> 0h
43 (1185248267) (46A5740B) >> 0h
-------------------------------------------------------------------------------------
rgsabound(0).lLbound
44 (1185248268) (46A5740C) >> 0h
45 (1185248269) (46A5740D) >> 0h
46 (1185248270) (46A5740E) >> 0h
47 (1185248271) (46A5740F) >> 0h
由于 8 字节内存地址和填充 ,VBA 7 64 位的注释显示了SAFEARRAYBOUNDS[0...]
+24 Dec,+18 hex的偏移量。pvData
我希望这有助于进一步解释任何SafeArray
功能正在执行什么以及SafeArray
结构项的位置。如果有人手动操作SafeArray
结构,请注意任何填充并正确设置偏移量。
我还将尝试解决您关于 VT_I4(3) 或 VT_R4(4) 的问题。
在 VBA 中肯定有一些额外的事情发生,然后是 SafeArray.c 函数所执行的操作,因为从使用 SafeArrayDescriptorEx 创建一个初始化的空整数数组的测试开始,没有设置 cbElements,设置了前面的 VT。奇怪的是,VBA 整数数组仍然可以在没有将整数数组的 cbElements 设置为 2 个字节的情况下工作。创建 SafeArrayDescriptor 时,我现在手动设置 cbElements。
使用上述 VBA 示例创建时,cbElements 已正确设置。
在 SafeArray.c 函数中,它们不返回 SizeOf(VT_I4) 或 SizeOf(VT_R4),即 C 不支持,所以我假设在 VBA 中必须扩展 SafeArray.c 函数并满足 C 中未涵盖的数据类型.
对 C 有更多了解的人可能能够更好地澄清或解释。