Results 1 to 6 of 6

Thread: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    I have a byte array called mybytearray with the ascii (1 byte per character) characters "ABCD1234" and would like to split it into 2 equal parts of 4 characters each so I have an array of fixed length strings like this
    Code:
    dim mystrarray() as string*4
    redim mystrarray(1)
    I then need to copy this so I have declared CopyMemory using "as any" for the source and destination. The following code should make the bytes of the byte array copy into the array of fixed length strings
    Code:
    copymemory mystrarray(0),mybytearray(0),8
    This CRASHES THE PROGRAM THOUGH!!!!

    So then I tried
    Code:
    copymemory byval strptr(mystrarray(0)),mybytearray(0),8
    This didn't crash the program, but the destination array is not containing the input data!

    So then I tried
    Code:
    copymemory byval strptr(mystrarray(0)),byval strptr(strconv(mybytearray(),vbunicode)),8
    Again THE DESTINATION ARRAY IS NOT RECEIVING THE DATA FROM THE SOURCE!!!!!!!!!

    Someone please help me. Thanks, in advance.

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,263

    Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    You do realize, that you're trying to copy 8 bytes to the destination-string? And that your destination-string is declared to take 4 characters, 2 bytes each character (unicode).
    And i would try varptr on the source-array
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    This way works:

    Code:
    Private Type FixedStrType   'This ensures the fixed-length
        String_0 As String * 4  'strings are contiguous in memory
        String_1 As String * 4  'Fixed-length strings are Unicode too
    End Type                    'Verify that by assigning any Unicode char
    
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    
    Private Sub Main()
        Dim MyByteArray() As Byte, MyFixedStr As FixedStrType
    
        MyByteArray = "ABCD1234"    'UBound(MyByteArray) = 15
    
       'Avoid Unicode-ANSI conversion by passing a pointer to MyFixedStr
       'Prevent CopyMemory from copying more than MyFixedStr can receive
       'by limiting the number of bytes copied to the size of FixedStrType
        CopyMemory ByVal VarPtr(MyFixedStr), MyByteArray(0), LenB(MyFixedStr)
    
        MsgBox MyFixedStr.String_0 & vbCrLf & MyFixedStr.String_1, vbInformation
    End Sub
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,263

    Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    Well, at least i was close
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    A userdefined type won't work for me. My input is a variable number of fixed length strings based on what file I'm loading. The number of fixed length strings will vary but the length of each string will NOT vary. So I must have something that can load a block of memory into an array of fixed length strings. So the formula should be

    Total Bytes = Number of Array elements * Number of Fixed Length Characters * 2
    (last "*2" is because of the fact that Unicode is 2 bytes per character)
    This should let me copy from a byte array directly into the array of fixed length strings, without any extra stupid hocus pocus to make VB "like" what I'm telling it to do.

    But it doesn't work. Why not?

  6. #6
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?

    The Total Bytes will depend on how you've populated the Byte Array in the first place (i.e. have you discarded the vbNewLines)
    If you have, then the Total Bytes will be UBound(ByteArray) + 1

    This appears to work:
    Code:
    Option Explicit
    
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
                        (Destination As Any, _
                         Source As Any, _
                         ByVal Length As Long)
    
    Private Const STRING_LENGTH As Integer = 8  ' Number of characters in a line of data
    Private Const HALF_LENGTH As Integer = STRING_LENGTH / 2
    
    Private Sub Command_Click()
    Dim intFile As Integer
    Dim intI As Integer
    Dim intJ As Integer
    Dim lngRecords As Long
    Dim bytData() As Byte
    Dim strLines() As String
    Dim strResults() As String * HALF_LENGTH
    Dim strTemp(1) As String * STRING_LENGTH
    intFile = FreeFile()
    '
    ' Read the entire file into a Byte Array
    ' Note that you can only use this method if there
    ' are no blank lines in the file
    '
    Open "C:\MyDir\MyData.txt" For Input As intFile
    bytData = Input(LOF(intFile), intFile)
    Close intFile
    '
    ' Calculate the Number of Records
    ' and establish the Results Array size
    '
    lngRecords = (UBound(bytData) + 1) / (2 * (STRING_LENGTH + 2))
    ReDim strResults((lngRecords * 2) - 1)
    Do
        '
        ' Copy the data to a temporary string
        ' and put the converted from Unicode data into the Results Array
        '
        CopyMemory ByVal strTemp(0), bytData(intJ), STRING_LENGTH
        strResults(intI) = StrConv(strTemp(0) & strTemp(1), vbFromUnicode)
        intJ = intJ + STRING_LENGTH
        '
        ' Check for end of line and skip over
        ' the vbNewLine
        '
        If (intJ - ((intI \ 2) * 4)) Mod (STRING_LENGTH * 2) = 0 Then
            intJ = intJ + 4
        End If
        intI = intI + 1
    Loop Until intI > UBound(strResults)
    For intI = 0 To UBound(strResults)
        Debug.Print strResults(intI)
    Next intI
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width