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个字节来,不知道是不是数据对齐有问题,希望高手解答!

解决方案 »

  1.   

    With Data1
        .fT = "ME"    .fS = "98765" 
     End Withfs不是long么?你的程序是不是有问题
      

  2.   

    应该是多1个字符串结束符 比如你上面字符串为 ME 那么结束符就是 chrb(69)+chrb(0)
      

  3.   

    ReDim data2(Len(Data1))
      CopyMemory data2(0), Data1, Len(Data1)
    改为
     ReDim data2(Len(Data1)+2)
      CopyMemory data2(0), Data1, Len(Data1)+2
      

  4.   

    问题出在这里:
    .fT = "ME"
    由于VB采用的是BString的格式存储的字符串,这点跟VC不同,VC是采用的CString保存的字符串,因此在VB中英文字母和数字每个也占2个字节。所以:
    Len(Data1)在这里等于6,应该改成LenB(Data1),这个才=8,OK?
      

  5.   

    刚才试了下
    结构体中的字符串比如"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
      

  6.   

    楼上的答案可以,多谢再次帮我解决问题,不过我想知道还有没有更简单,方便的方法,毕竟我的结构体比较多,而且结构体的内容比较复杂,不可能一个个来CopyMemory!多谢大家帮忙了!
      

  7.   

    Private Type my
        fS    As Long
        fT     As String * 2
        intReserved As Integer
    End Type
      

  8.   

    fT As String * 2
    固定字符串变量,占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.
      

  9.   

    程序有点错吧  ReDim data2(Len(Data1)-1)   '这个应该减1才对
      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一下。
      

  10.   

    不一定是4的倍数 要看string后面的变量类型定的
      

  11.   

    另外一中解决方法是不要定义成固定字符串:fT As String * 2:
    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!
      

  12.   

    Revised:
    另外一中解决方法是不要定义成固定字符串: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!
      

  13.   


    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!