在vba中可以在模块级别使用Type语句声明用户自定义的类型。
在VBA中调用DLL中的API函数时,经常需要传递正确的变量类型,才能正常使用API函数。
有不少API函数的参数是结构形式,在VBA中没有结构类型的变量,但是可以通过定义用户自定义类型的变量来当做结构传递。
当进行结构变量的传递时,有很多结构变量都需要预先设置结构的字节大小。
根据如何在vba中返回变量所分配的内存大小? 一文,我们了解到可以使用Len函数返回一些变量类型所分配的内存的字节大小,对于用户自定义类型的变量,它实际所分配的内存的字节大小是怎样的呢。
我们可以通过以下的代码来测试:
Type obj i As Long str As String j As Integer End Type Sub QQ1722187970() Dim o1 As obj With o1 .i = 1 .str = "a" .j = 2 End With Debug.Print VarPtr(o1), VarPtr(o1.i), VarPtr(o1.str), VarPtr(o1.j) Debug.Print VBA.Hex(VarPtr(o1)), VBA.Hex(VarPtr(o1.i)), VBA.Hex(VarPtr(o1.str)), VBA.Hex(VarPtr(o1.j)) End Sub
以上代码我们定义了一个用户自定义类型变量o1,它有三个元素,分别是Long, String,Integer类型。
当运行以下代码时,将在立即窗户中输出以下值:
2551336 2551336 2551340 2551344
26EE28 26EE28 26EE2C 26EE30
从结果可以看出用户自定义类型变量o1的内存地址(2551336)与第一个元素i的内存地址(2551336)是相同的。
o1的第一个元素i是long类型的,它占用的是4个字节的内存大小,故o1的第二个元素的str 内存地址(2551340)与第一个元素的内存地址(2551336 )相差4个字节。
o1的第二个元素为变长字符串变量str,由于变长字符串变量是以BSTR类型存储的, str变量实际存储的是字符串的第一个字符的内存地址,内存地址是4字节的,故str变量实际占用了4个字节,所以它的内存地址(2551340 )与第三个元素j的内存地址(2551344 )相差4个字节。
根据以上的分析结合o1元素的变量类型(4+4+2),实际o1分配的内存空间大小是10个字节,这个值刚好与len(o1)返回的值一致。
那是否可以下这样的结论:用户自定义类型变量所分配的内存大小与Len函数返回的值是一致的?
我们用以下的代码来测试:
Type obj i As Long str As String * 10 j As Integer End Type Sub QQ1722187970() Dim o1 As obj With o1 .i = 1 .str = "abc" .j = 2 End With Debug.Print Len(o1) Debug.Print VarPtr(o1), VarPtr(o1.i), VarPtr(o1.str), VarPtr(o1.j) Debug.Print VBA.Hex(VarPtr(o1)), VBA.Hex(VarPtr(o1.i)), VBA.Hex(VarPtr(o1.str)), VBA.Hex(VarPtr(o1.j)) End Sub
当运行以上代码后,将在立即窗户中输出以下值:
16
2551320 2551320 2551312 2551344
26EE18 26EE18 26EE10 26EE30
根据以上的结果,会容易产生歧义,好像o1的第二个元素str并不是接着o1的第一个元素i的,实际上对于定长字符串变量,VarPtr返回的值并不是实际的变量地址,有BUG。
通过内存查看软件查询后的结果如下图所示:
26EE18地址处开始存储o1变量的第一个元素i(4个字节),紧接着在26EE1C处开始存储字符串”abc”,然后存储“空格”,最后在26EE30处开始存储o1变量的第三个元素j,2个字节。
从图中可以看出,当用户自定义类型变量的元素含有定长字符串变量时,它所分配的内存大小与Len函数返回的值是不一致的,而与LenB函数返回的值是一致的,vba中一个字符用两个字节存储。
根据以上的分析,总结如下:
用户自定义类型变量所分配的内存大小有以下原则:
- 用户自定义类型变量的内存地址与第一个元素的内存地址一致
- 当用户自定义类型变量的元素类型为变长字符串变量时,所分配的内存地址是4个字节。
- 当用户自定义类型变量的元素类型为定长字符串变量时,所分配的内存地址是 2*字符数 字节。
根据以上的原则,可以结合各个元素所分配的内存大小,算出整个用户自定义类型变量所分配的内存大小字节数。
发表评论