在WINCC中使用WinSock控件进行TCP - IP通讯的例程(4)

2019-03-29 11:06

1、Variant数组转换成Byte数组

如前面提到在VBS中进行定义或转换,只能得到Variant类型数组,而在VB中将Variant类型数组转换成Byte型数组非常简单,如下面这个函数就可以实现这个功能:

Public Function CvVariantArray2vByteArray(inVarArray As Variant) As Variant Dim i As Integer, byteArray() As Byte ReDim byteArray(UBound(inVarArray)) For i = 0 To UBound(inVarArray) byteArray(i) = inVarArray(i) Next i CvVariantArray2vByteArray = byteArray End Function 在上面这个函数中,仅仅做了两件事,一是定义一个Byte数组,二是将Variant数组元素拷贝到Byte数组中。

2、十六进制数据格式字符串转换成相应的Byte数组

十六进制数据格式字符串是指字符串中的字符(两个一组)以十六进制数据格式表示,范围在“00”至“FF”之间,如下面这个字符串:

“EB9000FF”

将这样一个字符串转换成相应的Byte数组,其转换结果是: BYTE(3) = (0xEB,0x90,0x00,0xFF) 相应的VB函数代码如下所示:

Public Function CvHexStr2vOctetStr(vInstr As Variant) As Variant ' Use this to convert a Variant containing an ASCII encoded Hex string to a Variant Array of bytes ' this allows vbs to create Variants for ADSTYPE_OCTETSTRING from strings of ASCII characters 0-9 A-F Dim vOutArray() As Byte, i As Long Dim v As Variant ReDim vOutArray(0 To Len(vInstr) \\ 2 - 1) For i = 1 To Len(vInstr) \\ 2 vOutArray(i - 1) = Val(\Mid(vInstr, 2 * i, 1))

15

Next i CvHexStr2vOctetStr = vOutArray End Function 该函数的工作原理如下(以“EB9000FF”为例):

字符串vInstr = “EB9000FF” 是一个Unicode字符串,在内存中的存放的十六进制字节序为“45-00-42-00-39-00-30-00-30-00-30-00-46-00-46-00”,字符串长是8(Len函数)。

新建一个Byte数组,数组元素个数为4。

Mid函数是从指定字符串中返回指定数目的字符(注意不是字节),该函数以字符为基本操作元素,不是字节,由于在VB中,字符以Unicode格式(UCS-2/UTF-16 LE,双字节)表示,For循环开始时(i = 0),Mid(vInstr, 2 * i - 1, 1)首先取出第一个字符,即“E”(双字节十六进制“0045”,小端序),这个字符是十六制格式的,所以在前面加上“&H”前缀表示十六进制书写格式,将这个十六进制格式字符经Val函数转换成对应的数字,即14,由于这个字符是字节中的高4位,所以需要*16,等于224。

类似,取出同一字节中的低4位“B”并转换成相应的数字11,并与高4位数字相加,最终结果是235,在内存中存放的十六进制字节为“EB”。

循环结束后,得到字节数组(0xEB,0x90,0x00,0xFF)。

3、四字节十六进制数据格式字符串转换成单精度浮点数据

在IEEE 754标准中定义了单精度浮点数采用32位二进制数据(4字节)表示,二进制数据按位分割成符号位、指数域和尾数域,将浮点数转换成实数,需要按公式进行计算。如果在VBS中处理这样的转换,需要进行移位、判断、计算等多步处理,比较繁琐,运行效率也不见得有多高,而在VB中进行这样的转换处理是很方便的。

比如在VBS中使用通讯控件接收数据,在接收到的数据包中有四个字节的数据(9A,99, E5,41),这四个字节的数据表示一个IEEE单精度浮点数,在字节流中以小端序(LE)传输(41是高有效字节MSByte),以DWORD表示即为0x41E5999A,转换成单精度浮点数即为28.7。

这样的字节流在通讯控件接收到以后,存放在Byte数组中,在内存中存储的字节为9A-99-E5-41,其实这正是IEEE单精度浮点数在内存中的存放格式,如果能将该内存区(4字节)拷贝给一个float型变量,就可以很方便的完成转换工作。但在VBS中没有直接对内存区进行操作的命令或函数,所以这个转换工作需要放在DLL中进行。

16

这个四字节的Byte数组,可以直接通过VB函数转换成float。出于学习的目的,先将Byte数组转换成字符串,再将字符串转换成float。

将Byte数组转换成字符串的工作放在VBS中进行,代码如下: ?将接收到的BYTE()型数据转换为String型数据 For i = 0 To 3 strFromRec = strFromRec & Right(\Next 上面代码中strReceive变量存放的即为接收到的Byte数组数据,在VBS中可以使用Mid(或MidB)函数直接操作Byte数组(一般用来操作字符串String),其中MidB函数中的参数以字节为操作对象,MidB函数返回一个ASCII字符(数据类型是字符串,但在字存中还是一个字节数据,该字节数据为ASCII字符对应的ASCII字符码,范围“00”~“FF”之间)。

上面的代码是依次提取字节流中的字节,然后通过AscB函数将提取的ASCII字符转换成对应的ASCII字符码,再用Hex函数将字符码转换成十六进制数据格式表示的字符串。其中Right函数的使用是为了保持0~F字符码转换后的双字符格式。

将字符串转换成float的VB函数代码如下:

Private Declare Sub CopyMemory Lib \As Any, Source As Any, ByVal Length As Long) ?------------------------------------------------------------------------------ Public Function CvHexStr2vReal2(vInstr As Variant) As Variant Dim l As Long Dim f As Single Dim str As String Dim i As Integer str = \For i = 4 To 1 Step -1 str = str & Mid(vInstr, i * 2 - 1, 2) Next i l = Val(\CopyMemory f, l, 4 CvHexStr2vReal2 = f End Function 上面的程序代码中,首先对输入的字符串进行了高低位互换,这是可以理解的,因为

17

对于字符串或字节数组,在内存中的存放是按书写顺序由高到低存放的,在使用Val函数将字符串表达式传换成对应的整型数据前,字符串中的字节顺序排列是9A99E541,直接使用Val函数转换成整型数据是0x9A99E541,由于VB中整型数据是小端序存储方式,则在内存中的存放顺序是,由低地址到高地址是41-E5-99-9A,使用API函数CopyMemory进行内存拷贝是按字节顺序依次拷贝的,拷贝到浮点数变量内存中也是由低地址到高地址41-E5-99-9A排列,而VB对浮点型数据内存的解析同样采用小端序方式解析出来,最终得出的不是正确的结果,所以必须进行高低位字节的转换处理。

函数代码的工作过程是这样的:首先将输入的字符串进行高低字节互换,然后将互换后的字符串用Val函数按十六进制数据格式转换成整型数据,再用CopyMemory函数将整型数据内存区拷贝到浮点数内存区,最后函数返回的数据就是转换后的浮点数。

在函数转换处理过程中的变量在内存中的存放情况如下所示: 输入字符串:“9A99E541”

输入字符串在内存中存储的十六进制数据及顺序: 39-00-41-00-39-00-39-00-45-00-35-00-34-00-31-00

高低位互换后的字符串在内存中存储的十六进制数据及顺序: 34-00-31-00-45-00-35-00-39-00-39-00-39-00-41-00 转换成整型后在内存中存储的十六进制数据及顺序: 9A-99-E5-41

转换成单精度数据后在内存中存储的十六进制数据及顺序: 9A-99-E5-41 函数返回结果:28.7

18

参考资料:

1、VBS用户手册 2、WinCC中的画面模板

3、在VB6中用CopyMemory拷贝字符串的种种猫腻 4、关于字符编码,你所需要知道的 5、深入浅出浮点数

19


在WINCC中使用WinSock控件进行TCP - IP通讯的例程(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:上海市住宅设计标准

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: