变体类型Variant

变体类型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
指示值为引
<think>我们正在讨论的是CANdela Studio中影响CFG变体(Variant)兼容性的设置。根据之前的对话,我们知道在导入CDD到CFG时可能出现变体相关错误(如Missing mandatory value. No variant selected for legacy diagnostic data)。因此,我们需要在CANdela Studio中检查哪些设置会影响变体兼容性。 在CANdela Studio中,变体Variant)通常用于支持不同的诊断配置(例如Legacy Diagnostic Data和Standard Diagnostic Data)。影响CFG变体兼容性的关键设置包括: 1. **诊断会话配置(Diagnostic Session Configuration)**:在CANdela Studio中,诊断会话(如Default Session,Extended Session等)可能关联不同的变体。需要检查每个会话下激活的变体设置。 2. **安全等级配置(Security Level Configuration)**:安全访问状态机可能关联变体,确保安全等级与变体的兼容性。 3. **DID配置(DID Configuration)**:在创建DID时,需要指定该DID属于哪个变体(Legacy或Standard)。在CDD中编辑DID时,可以设置Variant Criterion(变体条件),这将直接影响导入CFG后该DID的变体归属。 4. **变体条件(Variant Criterion)**:这是最重要的设置。在CANdela Studio中,通常在项目树中有一个专门的节点“Variant Criteria”或“Variants”。在这里定义变体(如LegacyDiagnosticData),并设置其条件(例如,设置为TRUE表示激活)。在DID、服务等元素中引用这个变体条件,以决定它们在哪些变体下生效。 5. **服务配置(Service Configuration)**:对于UDS服务(如$22 ReadDataByIdentifier),需要检查服务是否关联了正确的变体条件。 具体操作步骤(在CANdela Studio中): 1. 打开CDD文件。 2. 在项目树中,查找“Variant Criteria”或类似节点。如果没有显式节点,可能在“Project Settings”或“General Settings”中。 3. 检查是否定义了变体条件(如LegacyDiagnosticData)。确保需要激活的变体条件设置为TRUE(或根据条件表达式设置)。 4. 检查DID配置: - 选择具体的DID(如0xFE01),查看其属性。 - 在属性中,找到“Variant Criterion”或“Variant”设置,确保它关联了正确的变体(例如LegacyDiagnosticData)。 5. 检查诊断会话和安全等级是否与变体条件一致。 注意:在CANdela Studio中设置变体条件后,导出CDD再导入CFG时,CFG应该能够正确识别变体,避免出现“No variant selected”的错误。 如果CDD中没有设置变体条件,那么需要在CANdela Studio中添加: - 右键点击“Variant Criteria”节点(或类似节点),选择“Add Variant Criterion”。 - 命名变体(例如LegacyDiagnosticData),并设置条件(通常设置为TRUE)。 - 对于需要属于该变体的DID,在其属性中关联这个新添加的变体条件。 这样,当CDD导入CFG时,变体设置会被正确传递,CFG中相应的变体属性就会被激活,从而解决兼容性问题。 引用说明: [^1] 提到在CFG中需要验证变体选择,而变体设置源自CDD文件。 [^2] 在创建DID时,虽然没有直接提到变体设置,但DID配置中包含多个Data,同样需要关联变体。 因此,在CANdela Studio中正确配置变体条件是确保CFG兼容性的关键。 </think>在CANdela Studio中,影响CFG变体(Variant)兼容性的关键设置主要包括以下四个方面: ### 1. **诊断会话变体关联** 在诊断会话配置中需明确指定变体激活规则: ```mermaid graph LR A[Default Session] -->|激活| B[Standard Variant] C[Extended Session] -->|激活| D[Legacy Variant] ``` - **位置**:`Session Configuration > Session Properties` - **关键参数**:`Variant Activation Condition`(必须为每个会话定义激活条件) - **影响**:未正确定义会话-变体映射会导致CFG导入时提示"未选择变体"[^1][^2] ### 2. **DID变体归属配置** 创建DID时需显式指定变体类型: ```mermaid graph TD E[DID 0xFE01] --> F[Data Element 1] E --> G[Data Element 2] E --> H{Variant} H --> I[Legacy] H --> J[Standard] ``` - **配置路径**:`Diagnostic Data > DIDs > DID Properties` - **必填项**:`VariantCriterion`(建议使用布尔表达式如 `LegacyDiagnosticData = TRUE`) - **影响**:未指定变体的DID在导入CFG时触发"Missing mandatory value"错误[^2] ### 3. **全局变体开关** 项目级变体控制参数: - **位置**:`Project Settings > Variant Handling` - **关键开关**: - `SupportLegacyVariant`(必须启用) - `VariantSelectionMechanism`(应设为"Explicit") - **数据验证**:启用`ValidateVariantConsistency`可提前检测冲突 ### 4. **服务级变体约束** UDS服务需声明变体兼容性范围: ```xml <service id="0x22"> <variantConstraints> <variant type="LEGACY" support="true"/> <variant type="STANDARD" support="true"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值