Ayala 发表于 2019-8-28 20:12:40

关于vb6.0的Variant结构体

```
Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal cBytes As Long)

Private Type mVar
    tyAs Integer '数据类型
    tyl As Integer '数据类型子类型
    ttAs Long    '备用 储存dec类型高32位
    loAs Long    '数据
    hiAs Long
End Type

Private Sub Form_Load()

    Dim ss As String
    Dim aa As Variant
    Dim bb As mVar
   
    aa = 5
    memcpy VarPtr(bb.ty), VarPtr(aa), 16
    bb.lo = 333
    memcpy VarPtr(aa), VarPtr(bb.ty), 16
    MsgBox aa

End Sub
```

0xAA55 发表于 2019-8-30 03:25:57

原来如此,了解了

Ayala 发表于 2019-8-30 19:54:31

0xAA55 发表于 2019-8-30 03:25
原来如此,了解了

研究下每种类型以及子类型代表什么 虽然以前就知道这结构 但是一直没去解析 也没查到完整的资料

系统消息 发表于 2019-8-30 20:03:21

0xAA55 发表于 2019-8-30 03:25
原来如此,了解了

纳尼,A5大神居然现在才了解?我不是记得你以前在群里讨论过这个结构吗

0xAA55 发表于 2019-8-31 06:25:45

系统消息 发表于 2019-8-30 20:03
纳尼,A5大神居然现在才了解?我不是记得你以前在群里讨论过这个结构吗

你记错了,我讨论的是SAFEARRAY

Ayala 发表于 2022-5-24 22:30:15

本帖最后由 Ayala 于 2022-5-24 23:20 编辑

0xAA55 发表于 2019-8-31 06:25
你记错了,我讨论的是SAFEARRAY

https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant
找到微软官方的了

typedef struct tagVARIANT {
union {
    struct {
      VARTYPE vt;
      WORD    wReserved1;
      WORD    wReserved2;
      WORD    wReserved3;
      union {
      LONGLONG   llVal;
      LONG         lVal;
      BYTE         bVal;
      SHORT      iVal;
      FLOAT      fltVal;
      DOUBLE       dblVal;
      VARIANT_BOOL boolVal;
      VARIANT_BOOL __OBSOLETE__VARIANT_BOOL;
      SCODE      scode;
      CY         cyVal;
      DATE         date;
      BSTR         bstrVal;
      IUnknown   *punkVal;
      IDispatch    *pdispVal;
      SAFEARRAY    *parray;
      BYTE         *pbVal;
      SHORT      *piVal;
      LONG         *plVal;
      LONGLONG   *pllVal;
      FLOAT      *pfltVal;
      DOUBLE       *pdblVal;
      VARIANT_BOOL *pboolVal;
      VARIANT_BOOL *__OBSOLETE__VARIANT_PBOOL;
      SCODE      *pscode;
      CY         *pcyVal;
      DATE         *pdate;
      BSTR         *pbstrVal;
      IUnknown   **ppunkVal;
      IDispatch    **ppdispVal;
      SAFEARRAY    **pparray;
      VARIANT      *pvarVal;
      PVOID      byref;
      CHAR         cVal;
      USHORT       uiVal;
      ULONG      ulVal;
      ULONGLONG    ullVal;
      INT          intVal;
      UINT         uintVal;
      DECIMAL      *pdecVal;
      CHAR         *pcVal;
      USHORT       *puiVal;
      ULONG      *pulVal;
      ULONGLONG    *pullVal;
      INT          *pintVal;
      UINT         *puintVal;
      struct {
          PVOID       pvRecord;
          IRecordInfo *pRecInfo;
      } __VARIANT_NAME_4;
      } __VARIANT_NAME_3;
    } __VARIANT_NAME_2;
    DECIMAL decVal;
} __VARIANT_NAME_1;
} VARIANT;

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f
typedefenum tagVARENUM
{
   VT_EMPTY = 0x0000,
   VT_NULL = 0x0001,
   VT_I2 = 0x0002,
   VT_I4 = 0x0003,
   VT_R4 = 0x0004,
   VT_R8 = 0x0005,
   VT_CY = 0x0006,
   VT_DATE = 0x0007,
   VT_BSTR = 0x0008,
   VT_DISPATCH = 0x0009,
   VT_ERROR = 0x000A,
   VT_BOOL = 0x000B,
   VT_VARIANT = 0x000C,
   VT_UNKNOWN = 0x000D,
   VT_DECIMAL = 0x000E,
   VT_I1 = 0x0010,
   VT_UI1 = 0x0011,
   VT_UI2 = 0x0012,
   VT_UI4 = 0x0013,
   VT_I8 = 0x0014,
   VT_UI8 = 0x0015,
   VT_INT = 0x0016,
   VT_UINT = 0x0017,
   VT_VOID = 0x0018,
   VT_HRESULT = 0x0019,
   VT_PTR = 0x001A,
   VT_SAFEARRAY = 0x001B,
   VT_CARRAY = 0x001C,
   VT_USERDEFINED = 0x001D,
   VT_LPSTR = 0x001E,
   VT_LPWSTR = 0x001F,
   VT_RECORD = 0x0024,
   VT_INT_PTR = 0x0025,
   VT_UINT_PTR = 0x0026,
   VT_ARRAY = 0x2000,
   VT_BYREF = 0x4000
} VARENUM;

https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/vartype-constants
Constant        Value        Description
vbEmpty        0        Uninitialized (default)
vbNull        1        Contains no valid data
vbInteger        2        Integer
vbLong        3        Long integer
vbSingle        4        Single-precision floating-point number
vbDouble        5        Double-precision floating-point number
vbCurrency        6        Currency
vbDate        7        Date
vbString        8        String
vbObject        9        Object
vbError        10        Error
vbBoolean        11        Boolean
vbVariant        12        Variant (used only for arrays of variants)
vbDataObject        13        Data access object
vbDecimal        14        Decimal
vbByte        17        Byte
vbLongLong        20        LongLong integer (valid on 64-bit platforms only)
vbUserDefinedType        36        Variants that contain user-defined types
vbArray        8192        Array

0xAA55 发表于 2022-5-25 10:39:45

Ayala 发表于 2022-5-24 22:30
https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant
找到微软官方的了



这几个东西在 MSVC 的头文件里有。

AyalaRs 发表于 2025-9-19 14:07:59

本帖最后由 AyalaRs 于 2025-9-19 14:10 编辑

Option Explicit

' Variable type constants
Const vbEmpty As Integer = 0             ' Uninitialized (default)
Const vbNull As Integer = 1            ' Contains no valid data
Const vbInteger As Integer = 2         ' Integer
Const vbLong As Integer = 3            ' Long integer
Const vbSingle As Integer = 4            ' Single-precision floating-point number
Const vbDouble As Integer = 5            ' Double-precision floating-point number
Const vbCurrency As Integer = 6          ' Currency
Const vbDate As Integer = 7            ' Date
Const vbString As Integer = 8            ' String
Const vbObject As Integer = 9            ' Object
Const vbError As Integer = 10            ' Error
Const vbBoolean As Integer = 11          ' Boolean
Const vbVariant As Integer = 12          ' Variant (used only for arrays of variants)
Const vbDataObject As Integer = 13       ' Data access object
Const vbDecimal As Integer = 14          ' Decimal
Const vbByte As Integer = 17             ' Byte
Const vbLongLong As Integer = 20         ' LongLong integer (valid on 64-bit platforms only)
Const vbUserDefinedType As Integer = 36' Variants that contain user-defined types
Const vbArray As Integer = 8192          ' Array

Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal cBytes As Long)


Private Type mVar
    tyAs Integer '数据类型
    tyl As Integer '数据类型子类型
    ttAs Long    '备用 储存dec类型高32位
    loAs Long    '数据
    hiAs Long
End Type


Private Sub main()

   
    Dim a As Variant
    Dim b As Variant
   
    Dim bb As mVar
   
    'bb.ty = &H15 '报错,提示不支持
    bb.ty = vbDecimal
   
    bb.lo = &HFFFFFFF1
    bb.hi = &HFFFFFFFF
    bb.tt = 0
    bb.tyl = 0
   
    memcpy VarPtr(a), VarPtr(bb.ty), 16
   
    bb.lo = &HFFFFFFF2
    bb.hi = &HFFFFFFFF
    bb.tt = 0
    bb.tyl = 0
   
    memcpy VarPtr(b), VarPtr(bb.ty), 16
   
   
    Debug.Print a
    Debug.Print b
   
    MsgBox a + b

End Sub



好像没办法让vb6直接支持ULONGLONG @YY菌

YY菌 发表于 2025-9-22 10:11:17

AyalaRs 发表于 2025-9-19 14:07
好像没办法让vb6直接支持ULONGLONG @YY菌

你试试这个就晓得了:

Option Explicit

Private Declare Function PutMem2 Lib "msvbvm60" (ByRef Dst As Any, ByVal Src As Integer) As Long

Private Sub Command1_Click()
    Dim v As Variant
    v = 1234567890@
    PutMem2 v, 20
    Print v
End Sub

AyalaRs 发表于 2025-9-22 14:51:32

YY菌 发表于 2025-9-22 10:11
你试试这个就晓得了:

看前面 20 是VBLONGLONG 21才是ULONGLONG

YY菌 发表于 2025-9-23 08:51:27

AyalaRs 发表于 2025-9-22 14:51
看前面 20 是VBLONGLONG 21才是ULONGLONG

?打印ULongLong还是可以的,但是做加法运算的时候报错了(说明oleaut32.dll的VarAdd函数实现了LongLong运算,没有实现ULongLong运算嘛)。

gujin163 发表于 2025-9-23 09:00:37

感谢大佬分享~~
页: [1]
查看完整版本: 关于vb6.0的Variant结构体