在s7-1200/1500的数据类型中,variant是不太好理解的。请看它的在线帮助:
“variant 类型的参数是一个可以指向不同数据类型变量(而不是实例)的指针。 variant 指针可以是基本数据类型(例如,int 或 real)的对象。 还可以是 string、dtl、struct 类型的 array、udt、udt 类型的 array。 variant 指针可以识别结构,并指向各个结构元素。variant 数据类型的操作数不占用背景数据块或工作存储器中的空间。但是,将占用 cpu 上的存储空间。”
“variant 类型的变量不是一个对象,而是对另一个对象的引用。 在函数的块接口中的 var_in、var_in_out 和 var_temp 部分中,variant 类型的单个元素只能声明为形参。 因此,不能在数据块或函数块的块接口静态部分中声明,例如,因为各元素的大小未知。 所引用对象的大小可以更改。”
“可使用 variant 来生成常规函数块或函数。 调用某个块时,可以将该块的参数连接到任何数据类型的变量。 调用某个块时,除了传递变量的指针外,还会传递变量的类型信息。 块代码随后可以根据运行期间传递的变量类型来执行。”
英语词典对variant的解释:变体、多样的。
百度中的解释:“在vb中,variant 数据类型是所有没被显式声明(例如 dim、private、public 或 static等语句)为其他类型变量的数据类型。”
下面是我做的实验:
在一个项目中生成一个全局数据块“数据块_1”,在数据块中生成一些复合数据类型的变量(见下图)。
生成fb1,其输入参数“变体”的数据类型为variant。在ob1中调用fb1,实验表明,可以将输入参数“变体”的实参设置为简单数据类型的变量,还可以设置为数据块_1中的字符串、数组1、结构1、结构1中的元素,结构1.数组2和它的元素,数据类型为dtl的“日时”和它的元素,结构1.时间和它的元素,但是不能将“变体”的实参设置为字符串“串1”中的元素。
实验可知,在fb的接口区,可以生成input、inout和temp类型的variant变量,但是不能生成output和static类型的variant变量。
做过实验后,就比较好理解在线帮助中的话了。下面是我对variant的理解:
1)variant是可以指向不同数据类型的变量的指针。它几乎可以指向所有的变量。数据类型any的功能够强大了,它可以指向几乎所有的简单数据类型,和连续的地址区,但是不能像variant一样,指向复合数据类型。variant比any(任意)还要any,简直就是一个七十二变的孙悟空!
2)因为variant 数据类型的操作数的“实际”数据类型是可变的,甚至其实参“各元素的大小未知。所引用对象的大小可以更改。”所有它不像pointer和any那样,其实参有固定的字节数,所以“variant 数据类型的操作数不占用背景数据块或工作存储器中的空间。”
3)“除了传递变量的指针外,(variant)还会传递变量的类型信息。”
以variant变量“百变”的实参“数据块_1.结构1.时间.hour”(db2.dbb53)为例,它包含了变量的地址和各级的数据类型。
4)如果变量的实参是复合数据类型(包括多层嵌套的复合数据类型)或它的元素,或者变量或元素的大小可变,必须使用variant指针。
在s7-1500硬件平台下,variant 已经完全可以替代any的功能了。
variant 常用相关指令有
1;检查数据类型
typeof,typeofelements,eq_type,ne_type,eq_elemtype,ne_elemtype
2:数组相关指令
is_array,countofelements
3 读写variant指向的数据
variantget,variantput
4:数据传送
move_blk_variant
5:和db_any数据类型的转换
variant_to_db_any,db_any_to_variant