Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type my
fT As String * 2
fS As Long
End Type
Private Sub Command1_Click()
Dim Data1 As my
Dim data2() As Byte
Dim data3() As Byte
With Data1
.fT = "ME"
.fS = "98765"
End With ReDim data2(Len(Data1))
CopyMemory data2(0), Data1, Len(Data1)
FilePathName = "c:\b.vb"
If Dir(FilePathName) <> "" Then Kill FilePathName
fp = FreeFile()
Open FilePathName For Binary As #fp
Put #fp, 1, Data1
Close #fp
Open FilePathName For Binary As #fp
ReDim data3(LOF(fp))
Get #fp, 1, data3
Close #fp
Me.Print "data2 "; " data3"
For i = 0 To UBound(data2)
Me.Print data2(i) & " " & data3(i)
Next End Sub使用上面的代码后发现data2莫名其妙的多出2个字节来,不知道是不是数据对齐有问题,希望高手解答!
Private Type my
fT As String * 2
fS As Long
End Type
Private Sub Command1_Click()
Dim Data1 As my
Dim data2() As Byte
Dim data3() As Byte
With Data1
.fT = "ME"
.fS = "98765"
End With ReDim data2(Len(Data1))
CopyMemory data2(0), Data1, Len(Data1)
FilePathName = "c:\b.vb"
If Dir(FilePathName) <> "" Then Kill FilePathName
fp = FreeFile()
Open FilePathName For Binary As #fp
Put #fp, 1, Data1
Close #fp
Open FilePathName For Binary As #fp
ReDim data3(LOF(fp))
Get #fp, 1, data3
Close #fp
Me.Print "data2 "; " data3"
For i = 0 To UBound(data2)
Me.Print data2(i) & " " & data3(i)
Next End Sub使用上面的代码后发现data2莫名其妙的多出2个字节来,不知道是不是数据对齐有问题,希望高手解答!
.fT = "ME" .fS = "98765"
End Withfs不是long么?你的程序是不是有问题
CopyMemory data2(0), Data1, Len(Data1)
改为
ReDim data2(Len(Data1)+2)
CopyMemory data2(0), Data1, Len(Data1)+2
.fT = "ME"
由于VB采用的是BString的格式存储的字符串,这点跟VC不同,VC是采用的CString保存的字符串,因此在VB中英文字母和数字每个也占2个字节。所以:
Len(Data1)在这里等于6,应该改成LenB(Data1),这个才=8,OK?
结构体中的字符串比如"ME" 内存中占用2个字节 只不过因为有个变量 fS AS long 所以变量对齐时 会多出2个无用字符填补
结构体使用copymemory最好还是 依次复制结构体中每个变量
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type my
fT As String * 2
fS As Long
End Type
Private Sub Command1_Click()
Dim Data1 As my
Dim data2() As Byte
Dim data3() As Byte
With Data1
.fT = "MY"
.fS = "98765"
End With
ReDim data2(Len(Data1) - 1)
CopyMemory data2(0), Data1, 2
CopyMemory data2(2), Data1.fS, Len(Data1.fS)
FilePathName = "c:\b.vb"
If Dir(FilePathName) <> "" Then Kill FilePathName
fp = FreeFile()
Open FilePathName For Random As #fp Len = Len(Data1)
Put #fp, 1, Data1
Close #fp
Open FilePathName For Binary As #fp
ReDim data3(LOF(fp) - 1)
Get #fp, 1, data3
Close #fp
Me.Print "data2 "; " data3"
For i = 0 To UBound(data3)
Me.Print data2(i) & " " & data3(i)
Next End Sub
fS As Long
fT As String * 2
intReserved As Integer
End Type
固定字符串变量,占2个字节。
Private Type my
fT As String * 2 '固定字符串变量,占2个字节。
fS As Long 'Long变量,占4个字节。
End TypeReDim data2(Len(Data1) - 1)
CopyMemory data2(0), Data1, 2
CopyMemory data2(2), Data1.fS, Len(Data1.fS)注意LenB和Len的区别!
'Note: Windows packs the my structure but
'32-bit Visual Basic does not. Therefore, all members
'following the two-byte fT member are offset by
'2 bytes. To deal with this, we copy structure members
'to a byte array with the proper alignment and pass
'the byte array to my.
CopyMemory data2(0), Data1, Len(Data1)-------------------------------------------------
我的理解是这样,CopyMemory 的时候,并不是一个字节一个字节来拷
而是4个字节拷一次,这样子复制的时候,string这样的数组在另一个地方,
如果大小不是4的倍数,那拷过去就会多有些位置出问题了;
解决的方法就是把string*后面的数字改成4的整数倍,比如4,8,12例程:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Type my
fT As String * 8
fS As Double
End Type
Private Sub Command1_Click()
Dim Data1 As my
Dim data2() As Byte
Dim data3() As Byte
Dim fp As Integer
Dim FilePathName As String
Dim i As Long
With Data1
.fT = "123456" '只写了6个,后面应该有两个空格
.fS = 98765
End With
ReDim data2(Len(Data1) - 1)
CopyMemory data2(0), Data1, Len(Data1)
FilePathName = "c:\b.vb"
If Dir(FilePathName) <> "" Then Kill FilePathName
fp = FreeFile()
Open FilePathName For Binary As #fp
Put #fp, 1, Data1
Close #fp
Open FilePathName For Binary As #fp
ReDim data3(LOF(fp))
Get #fp, 1, data3
Close #fp
Debug.Print "data2 "; " data3"
For i = 0 To UBound(data2)
Debug.Print data2(i) & " " & data3(i)
NextEnd Subdata2 data3
49 49
50 50
51 51
52 52
53 53
54 54
32 32
32 32
0 0
0 0
0 0
0 0
208 208
28 28
248 248
64 64当然这样子可能要把string数组搞大一点,读出来的时候需要trim一下。
Private Type my
fT As String ’Variable-length String
fS As Double
End Type'Variable-length strings require extra work
Dim buff1() as Byte
buff1 = StrConv(Data1.fT & Chr$(0), vbFromUnicode)
ptr = VarPtr(buff1(0))
CopyMemory ByteArray(0), ptr, LenB(ptr)
这样一来就对齐了。
你自己试试看。
Good Luck!
另外一中解决方法是不要定义成固定字符串:fT As String * 2:
Private Type my
fT As String ’Variable-length String
fS As Long
End Type'Variable-length strings require extra work
Dim buff1() as Byte
buff1 = StrConv(Data1.fT & Chr$(0), vbFromUnicode)
ptr = VarPtr(buff1(0))
CopyMemory ByteArray(0), ptr, LenB(ptr)
这样一来就对齐了。
你自己试试看。
Good Luck!
Revised again:
另外一中解决方法是不要定义成固定字符串:fT As String * 2:
Private Type my
fT As String ’Variable-length String
fS As Long
End Type'Variable-length strings require extra work
Dim buff1() as Byte
buff1 = StrConv(Data1.fT & Chr$(0), vbFromUnicode)
ptr = VarPtr(buff1(0))
ReDim ReDim data2(LenB(Data1)-1)
CopyMemory data2(0), ptr, LenB(ptr)
这样一来就对齐了。
你自己试试看。
Good Luck!