主题:[讨论]CopyMemory 从一个字节数组中提取各种类型的数据的问题
[code=c]
Option Explicit
Private Declare Sub CopyMemoryAny Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Long, pSrc As Long, ByVal ByteLen As Long)
Private Type Rec_Data2
'自定义结构体,36字节
rd_time(2) As Byte
rd_yali As Integer
rd_maxYali As Integer
rd_liu As Integer
rd_midu As Integer
rd_tai As Integer
rd_zhuJiang As Single
rd_shui As Integer
rd_sha As Integer
rd_state As Byte
rd_qksm As Byte
rd_stuff(12) As Byte
End Type
Private Sub Command1_Click()
'创建测试文件
Dim fNo As Integer
Dim i As Integer
Dim j As Integer
Dim tmp As Rec_Data2
fNo = FreeFile
Open "e:\test1.txt" For Binary As fNo
For i = 0 To 1
For j = 0 To 2
tmp.rd_time(j) = Rnd() * 60
Next
tmp.rd_yali = Rnd() * 5
tmp.rd_maxYali = Rnd() * 5
tmp.rd_liu = Rnd() * 50
tmp.rd_midu = Rnd() * 3
tmp.rd_tai = Rnd() * 200
tmp.rd_zhuJiang = Rnd() * 500
tmp.rd_shui = Rnd() * 10
tmp.rd_sha = Rnd() * 10
tmp.rd_state = Rnd() * 255
tmp.rd_qksm = Rnd() * 255
For j = 0 To 10
tmp.rd_stuff(j) = 32
Next
tmp.rd_stuff(11) = 13
tmp.rd_stuff(12) = 10
Debug.Print "-----------------------------------"
PrintType tmp
Put #fNo, , tmp
Next
Close fNo
End Sub
Private Sub Command2_Click()
'读取测试文件
Dim fNo As Integer
Dim i As Integer
Dim tmp As Rec_Data2
Dim bytArr() As Byte
Dim p2 As Integer '2字节
Dim p4 As Single '4字节
ReDim bytArr(36) As Byte '不知为何这里的下标要定义成36。为35时后会多读出一个全为0的bytArr
fNo = FreeFile
Open "e:\test1.txt" For Binary As fNo
Do While Not EOF(fNo)
Get fNo, i * 36 + 1, bytArr
[color=red]'单独地一个一个地取出,正确
CopyMemory ByVal VarPtr(p2), ByVal VarPtr(bytArr(3)), 2
Debug.Print p2
CopyMemoryAny p4, bytArr(13), 4
Debug.Print p4
'作为一个整体(自定义结构体),数值不正确
CopyMemoryAny tmp, bytArr(0), 36
Debug.Print "======================================="
PrintType tmp
[/color]
i = i + 1
Loop
Close fNo
End Sub
Private Function PrintType(ByRef typRec As Rec_Data2) As Long
'打印出结构体的所有成员
'要是有实现了IEnumerator接口的Type就好了,能用for each
Dim i As Integer
For i = 0 To 2
Debug.Print "rd_time("; i; ")="; typRec.rd_time(i)
Next
Debug.Print "rd_yali="; typRec.rd_yali
Debug.Print "rd_maxYali="; typRec.rd_maxYali
Debug.Print "rd_liu="; typRec.rd_liu
Debug.Print "rd_midu="; typRec.rd_midu
Debug.Print "rd_tai="; typRec.rd_tai
Debug.Print "rd_zhuJiang="; typRec.rd_zhuJiang
Debug.Print "rd_shui="; typRec.rd_shui
Debug.Print "rd_sha="; typRec.rd_sha
Debug.Print "rd_state="; typRec.rd_state
Debug.Print "rd_qksm="; typRec.rd_qksm
End Function
[/code]
Option Explicit
Private Declare Sub CopyMemoryAny Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Long, pSrc As Long, ByVal ByteLen As Long)
Private Type Rec_Data2
'自定义结构体,36字节
rd_time(2) As Byte
rd_yali As Integer
rd_maxYali As Integer
rd_liu As Integer
rd_midu As Integer
rd_tai As Integer
rd_zhuJiang As Single
rd_shui As Integer
rd_sha As Integer
rd_state As Byte
rd_qksm As Byte
rd_stuff(12) As Byte
End Type
Private Sub Command1_Click()
'创建测试文件
Dim fNo As Integer
Dim i As Integer
Dim j As Integer
Dim tmp As Rec_Data2
fNo = FreeFile
Open "e:\test1.txt" For Binary As fNo
For i = 0 To 1
For j = 0 To 2
tmp.rd_time(j) = Rnd() * 60
Next
tmp.rd_yali = Rnd() * 5
tmp.rd_maxYali = Rnd() * 5
tmp.rd_liu = Rnd() * 50
tmp.rd_midu = Rnd() * 3
tmp.rd_tai = Rnd() * 200
tmp.rd_zhuJiang = Rnd() * 500
tmp.rd_shui = Rnd() * 10
tmp.rd_sha = Rnd() * 10
tmp.rd_state = Rnd() * 255
tmp.rd_qksm = Rnd() * 255
For j = 0 To 10
tmp.rd_stuff(j) = 32
Next
tmp.rd_stuff(11) = 13
tmp.rd_stuff(12) = 10
Debug.Print "-----------------------------------"
PrintType tmp
Put #fNo, , tmp
Next
Close fNo
End Sub
Private Sub Command2_Click()
'读取测试文件
Dim fNo As Integer
Dim i As Integer
Dim tmp As Rec_Data2
Dim bytArr() As Byte
Dim p2 As Integer '2字节
Dim p4 As Single '4字节
ReDim bytArr(36) As Byte '不知为何这里的下标要定义成36。为35时后会多读出一个全为0的bytArr
fNo = FreeFile
Open "e:\test1.txt" For Binary As fNo
Do While Not EOF(fNo)
Get fNo, i * 36 + 1, bytArr
[color=red]'单独地一个一个地取出,正确
CopyMemory ByVal VarPtr(p2), ByVal VarPtr(bytArr(3)), 2
Debug.Print p2
CopyMemoryAny p4, bytArr(13), 4
Debug.Print p4
'作为一个整体(自定义结构体),数值不正确
CopyMemoryAny tmp, bytArr(0), 36
Debug.Print "======================================="
PrintType tmp
[/color]
i = i + 1
Loop
Close fNo
End Sub
Private Function PrintType(ByRef typRec As Rec_Data2) As Long
'打印出结构体的所有成员
'要是有实现了IEnumerator接口的Type就好了,能用for each
Dim i As Integer
For i = 0 To 2
Debug.Print "rd_time("; i; ")="; typRec.rd_time(i)
Next
Debug.Print "rd_yali="; typRec.rd_yali
Debug.Print "rd_maxYali="; typRec.rd_maxYali
Debug.Print "rd_liu="; typRec.rd_liu
Debug.Print "rd_midu="; typRec.rd_midu
Debug.Print "rd_tai="; typRec.rd_tai
Debug.Print "rd_zhuJiang="; typRec.rd_zhuJiang
Debug.Print "rd_shui="; typRec.rd_shui
Debug.Print "rd_sha="; typRec.rd_sha
Debug.Print "rd_state="; typRec.rd_state
Debug.Print "rd_qksm="; typRec.rd_qksm
End Function
[/code]