如何取得variant内含的数组的首元素的地址

捧剑者 2013-03-30 12:09:55
加精
r...........t
...全文
2142 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaocongzhi 2013-04-08
  • 打赏
  • 举报
回复
解析确实有点麻烦
速度放缓 2013-04-06
  • 打赏
  • 举报
回复
好难的样子 无语了,,,
worldy 2013-04-06
  • 打赏
  • 举报
回复
要如LS那么复杂? VarPtr(A(0)),不行吗?
mbugaifc 2013-04-03
  • 打赏
  • 举报
回复
qwegam 2013-04-03
  • 打赏
  • 举报
回复
太感谢啦~非常有用~~~
a823473385 2013-04-03
  • 打赏
  • 举报
回复
看看看看看那
u010146112 2013-04-03
  • 打赏
  • 举报
回复
的人与人的热议额热议特让他
ShiDaiNanSheng 2013-04-03
  • 打赏
  • 举报
回复
菜鸟飞过
Tiger_Zhao 2013-04-03
  • 打赏
  • 举报
回复
版主推荐只看分数的吗? 上次我回复的 一个关于数组长度判断的问题 更值得推荐。 那个不象本贴一样有直接的资料可查。
hugh_z 2013-04-03
  • 打赏
  • 举报
回复
learing.
ftjavayp 2013-04-03
  • 打赏
  • 举报
回复
挑灯夜话 2013-04-03
  • 打赏
  • 举报
回复
不错,太实用了,解决了问题
PctGL 2013-04-03
  • 打赏
  • 举报
回复
http://www.cnblogs.com/pctgl/articles/1540556.html

获取安全数组信息
 
Des:
获取安全数组的信息,包括安全数组结构内的所有数据
本来用结构做的话,更方便,但会增加代码量,而且用起来也会麻烦些,所以就用了N多变量了
有兴趣的朋友可以再改改

Private Function GetSafeArrayInfo(AnyArray As Variant, Optional sDimension As Integer, Optional LowerBound As Long, Optional UpperBound As Long, Optional Elements As Long, Optional Flags As Integer, Optional cbElements As Long, Optional cLocks As Long, Optional AddressOfData As Long) As Long
'**************************************************************
'*
'*  数组头地址 = GetSafeArrayInfo(数组 ,[维数],[下标],[上标],[元素个数],[属性],[元素长度],[锁定计数],[首元素地址])
'*
'*  result:  成功返回数组头地址;  返回 0 代表这是一个未被初始化过的数组
'*
'*  note:    除第1个参数外,均为输出型参数,要获取数组的什么信息,传入相应的变量,执行后,变量的值即为相应的数组数据
'*
'*           要获取多维数组的非第1维的上/下标,应按照下面的方法调用
'*
'*           GetSafeArrayInfo (数组, 指定一个维数,[下标],[上标]
'*
'**************************************************************

    Dim ArrayHeaderAddress  As Long
    Dim DimensionCount As Integer     '维数计次

    CopyMemory ArrayHeaderAddress, ByVal VarPtr(AnyArray) + 8, 4
    CopyMemory ArrayHeaderAddress, ByVal ArrayHeaderAddress, 4              '获取数组头地址
   
    If ArrayHeaderAddress < 1 Then Exit Function

    CopyMemory DimensionCount, ByVal ArrayHeaderAddress, 2                  '获取数组维数

    If sDimension > DimensionCount Then Exit Function                       '若指定的维数大于实际维数则退出

    CopyMemory LowerBound, ByVal (ArrayHeaderAddress + 16 + (DimensionCount - sDimension) * 8) + 4, 4 '获取下标
    CopyMemory Elements , ByVal (ArrayHeaderAddress + 16 + (DimensionCount - sDimension) * 8), 4

                                                   '获取指定维数下的元素个数
    UpperBound = Elements + LowerBound - 1                                '获取指定维数下的上标
   
    CopyMemory Flags, ByVal ArrayHeaderAddress + 2, 2                       '获取数组属性
    CopyMemory cbElements, ByVal ArrayHeaderAddress + 4, 2                  '获取数组单个元素长度
    CopyMemory cLocks, ByVal ArrayHeaderAddress + 8, 2                      '获取数组锁定计数
    CopyMemory AddressOfData, ByVal ArrayHeaderAddress + 12, 4              '获取数组首元素地址
   
    GetSafeArrayInfo = ArrayHeaderAddress
 
End Function


u010143656 2013-04-03
  • 打赏
  • 举报
回复
呵呵,留着好好学
GodYiKai 2013-04-03
  • 打赏
  • 举报
回复
只能麻烦点了,没别的办法
keithat 2013-04-03
  • 打赏
  • 举报
回复
学习了
Tiger_Zhao 2013-04-02
  • 打赏
  • 举报
回复
可以看出 TestByRef 是对原数组的引用,直接赋值和 TestByVal 都复制了数组。
Tiger_Zhao 2013-04-02
  • 打赏
  • 举报
回复
Option Explicit

Type userVARIANT
    vt              As Integer
    wReserved1      As Integer
    wReserved2      As Integer
    wReserved3      As Integer
    dwReserved1     As Long
    dwReserved2     As Long
End Type

Const VT_BYREF = &H4000

Sub Main()
    Dim arrVar      As Variant
    Dim a()         As Byte
    ReDim a(2)
    Debug.Print Hex(VarPtr(a(0)))

    arrVar = a
    Debug.Print Hex(GetpvData(VarPtr(arrVar)))

    TestByRef a
    TestByVal a
End Sub

Function GetpvData(ByVal pV As Long) As Long
    Dim v           As userVARIANT
    Dim sa          As SafeArray
    Dim pSA         As Long

    CopyMemory v, ByVal pV, Len(v)
    If CBool(v.vt And VT_BYREF) Then
        CopyMemory pSA, ByVal v.dwReserved1, 4
    Else
        pSA = v.dwReserved1
    End If

    CopyMemory sa, ByVal pSA, Len(sa)
    GetpvData = sa.pvData
End Function

Sub TestByRef(ByRef arrVar As Variant)
    Debug.Print Hex(GetpvData(VarPtr(arrVar)))
End Sub

Sub TestByVal(ByVal arrVar As Variant)
    Debug.Print Hex(GetpvData(VarPtr(arrVar)))
End Sub
输出:
3DBCCB0 3DBCCA0 3DBCCB0 3DBCC90
没加容错处理。
捧剑者 2013-04-02
  • 打赏
  • 举报
回复
多谢版主推荐
捧剑者 2013-04-02
  • 打赏
  • 举报
回复
赵老虎的函数:

Function GetpvData(ByVal pV As Long) As Long
    Dim v           As userVARIANT
    Dim sa          As SafeArray
    Dim pSA         As Long
 
    CopyMemory v, ByVal pV, Len(v)
    If CBool(v.vt And VT_BYREF) Then
        CopyMemory pSA, ByVal v.dwReserved1, 4
    Else
        pSA = v.dwReserved1
    End If
 
    CopyMemory sa, ByVal pSA, Len(sa)
    GetpvData = sa.pvData
End Function
嗯,这就是解析VARIANT及SAFEARRAY的具体实现了。
加载更多回复(17)

1,485

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧