变体类型Variant

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
变体类型Variant,能够在运行期间动态的改变类型。变体类型能支持所有简单的数据类型,如整型、浮点、字符串、布尔型、日期时间、货币及 OLE自动化对象等,不能够表达Object Pascal对象。
1.VarArrayCreate function
Creates a variant array.
创建一个变体类型的 数组
function VarArrayCreate(const Bounds: array of Integer; VarType: TVarType): Variant;
VarArrayOf function
Creates and fills a one-dimensional variant array.
创建并且填充一个一维的变体类型的数组。
function VarArrayOf(const Values: array of Variant): Variant;
VarArrayCreate, VarArrayOf Example
var
A: Variant;
begin
A := VarArrayCreate([0, 4], varVariant);
A[0] := 1;
A[1] := 1234.5678;
A[2] := 'Hello world';
A[3] := True;
A[4] := VarArrayOf([1, 10, 100, 1000]);
WriteLn(A[2]); { Hello world }
WriteLn(A[4][2]); { 100 }
end;
2.VarArrayLock function
Locks a variant array and returns a pointer to the data.
锁住一个变体类型的数组并且返回一个指向这个数据的指针。
function VarArrayLock(const A: Variant): Pointer;
VarArrayLock, VarArrayUnlock Example
type
PArrayData = ^TArrayData;
TArrayData = array[0..9, 1..3] of Integer;
var
A: Variant;
P: PArrayData;
I, J: Integer;
begin
A := VarArrayCreate([1, 3, 0, 9], varInteger);
P := VarArrayLock(A);
try
for I := 0 to 9 do
for J := 1 to 3 do
P^[I, J] := J * 10 + I;
finally
VarArrayUnlock(A);
end;
WriteLn(A[1, 9]); { 19 }
WriteLn(A[3, 4]); { 34 }
end;
3.VarArrayUnlock procedure
Unlocks a variant array.
procedure VarArrayUnlock(var A: Variant);
VARIANT 数据类型在文件OAIDL.IDL中定义如下:struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
ULONGLONG ullVal;
LONGLONG llVal;
LONG lVal;
BYTE bVal;
SHORT iVal;
FLOAT fltVal;
DOUBLE dblVal;
VARIANT_BOOL boolVal;
_VARIANT_BOOL 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 *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;
INT intVal;
UINT uintVal;
DECIMAL * pdecVal;
CHAR * pcVal;
USHORT * puiVal;
ULONG * pulVal;
ULONGLONG * pullVal;
INT * pintVal;
UINT * puintVal;
struct __tagBRECORD {
PVOID pvRecord;
IRecordInfo * pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};
VARIANT 数据结构包含两个域(如果不考虑保留的域)。vt域描述了第二个域的数据类型。为了使多种类型能够在第二个域中出现,我们定义了一个联合结构。所以,第二个域的名称随着vt域中输入值的不同而改变。用于指定vt域值情况的常量在联合的定义中以每一行的注释形式给出。
使用VARIANT和VARIANTARG数据结构要分两步完全。举一个例子,让我们考虑如下代码:
long lValue = 999;
VARIANT vParam;
vParam.vt = VT_I4;
vParam.lVal = lValue;
在第一行中指定数据类型。常量VT_I4表明在第二个域中将出现一个long型的数据。根据类型VARIANT的定义,可以得知,当一个long型数据存入VARIANT类型时,其第二个域使用的名称是lVal。
使用VARIANT来传递参数意味着非强类型语言(例如VBScript)能够调用使用强类型语言(C++)实现的方法。Invoke()方法的实现可以检查参数VARIANT封装的数值是否符合其正确的数据类型。如果符合,该类型将取出,并传递给调用方法。否则,Invoke()方法能够尝试使用 VariantChangeType()API函数来将该数值转换成正确的类型。
typedef unsigned short VARTYPE;
enum VARENUM
{ VT_EMPTY = 0,
VT_NULL = 1,
VT_I2 = 2,
VT_I4 = 3,
VT_R4 = 4,
VT_R8 = 5,
VT_CY = 6,
VT_DATE = 7,
VT_BSTR = 8,
VT_DISPATCH = 9,
VT_ERROR = 10,
VT_BOOL = 11,
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_DECIMAL = 14,
VT_I1 = 16,
VT_UI1 = 17,
VT_UI2 = 18,
VT_UI4 = 19,
VT_I8 = 20,
VT_UI8 = 21,
VT_INT = 22,
VT_UINT = 23,
VT_VOID = 24,
VT_HRESULT = 25,
VT_PTR = 26,
VT_SAFEARRAY = 27,
VT_CARRAY = 28,
VT_USERDEFINED = 29,
VT_LPSTR = 30,
VT_LPWSTR = 31,
VT_RECORD = 36,
VT_INT_PTR = 37,
VT_UINT_PTR = 38,
VT_FILETIME = 64,
VT_BLOB = 65,
VT_STREAM = 66,
VT_STORAGE = 67,
VT_STREAMED_OBJECT = 68,
VT_STORED_OBJECT = 69,
VT_BLOB_OBJECT = 70,
VT_CF = 71,
VT_CLSID = 72,
VT_VERSIONED_STREAM = 73,
VT_BSTR_BLOB = 0xfff,
VT_VECTOR = 0x1000,
VT_ARRAY = 0x2000,
VT_BYREF = 0x4000,
VT_RESERVED = 0x8000,
VT_ILLEGAL = 0xffff,
VT_ILLEGALMASKED = 0xfff,
VT_TYPEMASK = 0xfff
} ;
VARIANT支持的类型,也就是vt成员的取值如表所示。
  
类型名
含义
VT_EMPTY
指示未指定值
VT_NULL
指示空值(类似于 SQL 中的空值)
VT_I2
指示 short 整数
VT_I4
指示 long 整数
VT_R4
指示 float 值
VT_R8
指示 double 值
VT_CY
指示货币值
VT_DATE
指示 DATE 值
VT_BSTR
指示 BSTR 字符串
VT_DISPATCH
指示 IDispatch 指针
VT_ERROR
指示 SCODE
VT_BOOL
指示一个布尔值
VT_VARIANT
指示 VARIANTfar 指针
VT_UNKNOWN
指示 IUnknown 指针
VT_DECIMAL
指示 decimal 值
VT_I1
指示 char 值
VT_UI1
指示 byte
VT_UI2
指示 unsignedshort
VT_UI4
指示 unsignedlong
VT_I8
指示 64 位整数
VT_UI8
指示 64 位无符号整数
VT_INT
指示整数值
VT_UINT
指示 unsigned 整数值
VT_VOID
指示 C 样式 void
VT_HRESULT
指示 HRESULT
VT_PTR
指示指针类型
VT_SAFEARRAY
指示 SAFEARRAY
VT_CARRAY
指示 C 样式数组
VT_USERDEFINED
指示用户定义的类型
VT_LPSTR
指示一个以 NULL 结尾的字符串
VT_LPWSTR
指示由 nullNothingnullptrnull引用(在 Visual Basic 中为 Nothing) 终止的宽字符串
VT_RECORD
指示用户定义的类型
VT_FILETIME
指示 FILETIME 值
VT_BLOB
指示以长度为前缀的字节
VT_STREAM
指示随后是流的名称
VT_STORAGE
指示随后是存储的名称
VT_STREAMED_OBJECT
指示流包含对象
VT_STORED_OBJECT
指示存储包含对象
VT_BLOB_OBJECT
指示 Blob 包含对象
VT_CF
指示剪贴板格式
VT_CLSID
指示类 ID
VT_VECTOR
指示简单的已计数数组
VT_ARRAY
指示 SAFEARRAY 指针
VT_BYREF
指示值为引
variant:优雅的C++类型安全变体容器 摘要: 本文详细介绍了wheels库中的variant.hpp实现,这是一个类型安全的C++变体容器。文章从设计哲学入手,阐述了其在类型安全与灵活性之间的平衡,采用类型擦除和多态架构实现高效存储。核心实现部分重点解析了类型擦除机制、多层次的类型安全保障(包括编译期检查和运行时验证)、线程安全实现、完善的拷贝/移动语义支持,以及便捷的类型换运算符。该设计在保证类型安全的同时,提供了良好的性能和扩展性,是C++17之前实现变体容器的优秀解决方案。 阅读详情

相关推荐

76、C++ 变体类型variant)的全面解析

本文全面解析了 C++ 标准库中的变体类型variant),涵盖了基本规则、构造函数、析构函数、赋值运算符、修改器、值状态管理、辅助类、值访问方法、异常处理注意事项、性能优化策略以及实际应用场景。通过详细的技术解析和代码示例,帮助开发者更好地理解和高效使用 variant 类型,提高程序的灵活性和健壮性。

rr23456的博客 262

变体(Variant)类型枚举 VARENUM enumeration

在近期工作的过程中因为需要C++编写的ActiveX控件需要被C#调用,所以频繁地使用到Variant类型,而SafeArray的各种类型又是用枚举量标识的,所以需要经常查阅,就将MSDN的文档搬运至此

Theodore's Notes 1742

delphi-变体类型(variant)的介绍(流与变体类型的相互变体类型常用的函数

delphi-变体类型(variant)的介绍(流与变体类型的相互变体类型常用的函数

Variant 数组

Variant 数组 Variant: 一种可以拥有各种数据类型; 也可以告诉目前存储的数据是什么类型(通过使用VarType函数); 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法; variant数组只不过是variant型的数组,不必包含同类型的 数据; variant数组的创建方法: function VarArrayCreate(const Bo

1323

VBA实战(06) - 数组

Class06. 数组 定义 下面是几种常见定义数组的方法。 ' 定义一个一维数组,数据类型Variant,长度从0到5,实际控件有六个,长度为5 Dim arr(5) as String ' 定义一个一维数组,数据类型Variant,长度从1到5,实际控件有六个,长度为5 Dim arr(1 to 5) as String ' 可以省略As后面部分,等于 Dim arr2 () as Variant Dim arr(5) ' 一维数组,下标从0开始 arr2 = Array("你好", "世界") '

jie_ming514的博客 3764

VARENUM Enumeration

https://docs.microsoft.com/zh-cn/windows/desktop/api/wtypes/ne-wtypes-varenum   VARENUM Enumeration 2018/12/05 2 分钟阅读时长 Specifies the variant types. Syntax C++复制 typedef enum VARENUM { VT_EM...

thanklife的专栏 516

使用VARIANT传递数组的方法及步骤

在使用COM/DCOM写组件时经常要传递数组,一般比如SHORT,LONG等指针可以直接传递相应的指针,但是当遇到需要传递BYTE数组就有问题了,COM不支持BYTE类型参数,传递BYTE数组也就无从说起了。经过查找资料发现使用VARIANT变量可以传递任何类型的数组,随将使用VARIANT数组的方法总结一下。其实在VARIANT传递数组的方法非常简单,只要理解SAFEARRAY数组的使用方法即可

Joe_wang的专栏 1万+

Variant:为TypeScript带来强大的变体类型支持

Variant:为TypeScript带来强大的变体类型支持 在软件开发中,类型安全是确保代码质量的重要环节。今天,我们将向您推荐一个开源项目——Variant,它为TypeScript带来了类似于 ReasonML 中的变体类型variant type)功能,极大提升了类型系统的灵活性和安全性。 项目介绍 Variant 是一个开源项目,旨在将 ReasonML 中的变体类型概念引入 Type...

gitblog_00027的博客 499

关于COM中变体类型VARIANT

从com的设计初衷来讲,要达到跨语言的目的,但是c++啊,java,python,pascal什么的都是有自己的数据类型的,设计这个变体类型VARIANT就是为了达到这个目的,之所以称之为变体类型是因为它的类型不是固定的,基本上可以表示COM里面的任何基本类型和常见接口指针,从c++的本质来讲,VARIANT类型就是一个结构体,该结构体中有一个成员是表示该变量到底是个什么变量,也就是应该把这个表示

Neo的专栏 1773

C++11项目升级必看:MPark.Variant让你的代码兼容现代C++变体类型

MPark.Variant是一个为C++11/14/17实现的C++17 `std::variant`库,它能帮助开发者在旧项目中轻松使用现代C++的变体类型特性。基于为libc++实现的`std::variant`,并持续针对libc++的`std::variant`测试套件进行测试,为项目提供可靠的类型安全的联合类型支持。 ## 为什么选择MPark.Variant? 在C++17标准中引

gitblog_01067的博客 669

2020.3.27C++学习笔记——VARIANT变体数据类型实例

C++学习笔记——VARIANT变体数据类型实例 之前工作中看到了VARIANT数据类型,了解到在较复杂些的工程中,很少只用到一个语言,例如之前的html网页调用ActiveX控件,就至少使用了html,js,c++三种语言。而在工程测试过程中,难免会有不同语言编译的模块要进行数据的传输,此时对于数据类型的定义和声明十分重要。 例如,在html的OCX控件编写中,我发现VS自行生成的ActiveX...

CQ的学习笔记 1857

vb.net Dim 没有As 为变体Variant变量类型

Variant变体类型的可以理解为:还不知道它是什么类型,将来它会自动变成我想要的类型。即“可变体”。

1367

C++变体数据类型—— VARIANT

百度百科:Variant  音标 Phonetic symbol   [] 词性及解释 Part of speech and defination   n. 变体, 异体  a. 不同的, 有差别的  【计】 变体型  【化】 变体  【医】 变异的; 变异体, 变型, 变种  Variant 数据类型是所有没被显式声明(用如 Dim、Private、Public 或 Static等语句)为其他类...

yousss的博客 3万+

Delphi 变体类型Variant)的介绍(流与变体类型的相互换、变体类型常用的函数)

一、变体类型常用的函数介绍:         Variant: 一种可以拥有各种数据类型; 也可以告诉目前存储的数据是什么类型(通过使用VarType函数); 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法; variant数组只不过是variant型的数组,不必包含同类型的数据; 1、  VarArrayOf函数:更快捷的创建一维变体数组

crkres9527 2536

变体类型 Variant VARIANT

变体类型 Variant VARIANT class RTL_DELPHIRETURN Variant: public TVarDatatypedef struct tagVARIANT VARIANT; Variant Arrays V: Variant; V:= VarArrayCreate([0,9], varInteger); CreateOleObject...

weixin_30892889的博客 199

[]Delphi 变体类型Variant)的介绍(流与变体类型的相互换、变体类型常用的函数)...

Delphi 变体类型Variant)的介绍(流与变体类型的相互换、变体类型常用的函数) 一、变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型; 也可以告诉目前存储的数据是什么类型(通过使用VarType函数); 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法; variant数组只不过是varian...

weixin_30894389的博客 368
上一篇: VC中使用动态链接库DLL:静态调用和动态调用
下一篇: vba改动excel参数
HiRuyue
博客等级 码龄14年 47粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值