dcsimg
Results 1 to 7 of 7

Thread: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

  1. #1

    Thread Starter
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,057

    Arrow [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    This simple class makes it very easy to typecast a String into an Integer array. Treating a String as an array enables some kinds of String processing to be done much quicker than is possible with VB's intrinsic String functions.


    clsStrToIntArray.cls
    Code:
    
    Option Explicit
    
    Private Const FADF_AUTO      As Integer = &H1   'An array that is allocated on the stack.
    Private Const FADF_FIXEDSIZE As Integer = &H10  'An array that may not be resized or reallocated.
    
    Private Type SAFEARRAY1D    'Represents a safe array. (One Dimensional)
        cDims      As Integer   'The count of dimensions.
        fFeatures  As Integer   'Flags used by the SafeArray.
        cbElements As Long      'The size of an array element.
        cLocks     As Long      'The number of times the array has been locked without a corresponding unlock.
        pvData     As Long      'Pointer to the data.
        cElements  As Long      'The number of elements in the dimension.
        lLbound    As Long      'The lower bound of the dimension.
    End Type                    'http://msdn.microsoft.com/en-us/library/ms221482(v=vs.85).aspx
    
    Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef ArrayVar() As Any) As Long
    Private Declare Sub PutMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByVal NewVal As Long)
    
    Private Ptr  As Long
    Private SA1D As SAFEARRAY1D
    
    Private Sub Class_Initialize()
        With SA1D
            .cDims = 1
            .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE
            .cbElements = 2&
            .cLocks = 1&
            .lLbound = 1&
        End With
    End Sub
    
    'This should be the first method called right after instantiating
    'the class and should be invoked only once per class instance.
    'Pass the Integer array that will substitute for the String.
    
    Public Sub InitArray(ByRef IntArray_OUT() As Integer)
        Erase IntArray_OUT
        Ptr = VarPtrArray(IntArray_OUT())
        PutMem4 Ptr, VarPtr(SA1D)
    End Sub
    
    'This function typecasts the passed String into an Integer array.
    'That is, the characters of the String can be treated as elements
    'of the Integer array. Any number of Strings can be typecast to
    'the Integer array by calling this function repeatedly. However,
    'the array should not be Erased when assigning another String.
    'This function fails (returns False) if passed an empty string.
    
    Public Function CastString(ByRef String_IN As String) As Boolean
        Dim StrLen As Long
    
        If Ptr Then
            StrLen = Len(String_IN)
            If StrLen Then
                With SA1D
                   .pvData = StrPtr(String_IN)
                   .cElements = StrLen
                    CastString = .pvData <> 0&
                End With
            End If
        End If
    End Function
    
    Private Sub Class_Terminate()
        If Ptr Then PutMem4 Ptr, 0&
    End Sub
    
    
    modMain.bas
    Code:
    
    Option Explicit
    
    Private Sub Main()
        Dim aintChars() As Integer, i As Long
        Dim sControlChars As String, sPrintableChars As String
    
        sControlChars = Space$(31&)
        sPrintableChars = String$(224&, 0)
    
        With New clsStrToIntArray
           .InitArray aintChars()
    
            If .CastString(sPrintableChars) Then
                For i = LBound(aintChars) To UBound(aintChars)
                    aintChars(i) = i + 31&
                Next
                Debug.Print """" & sPrintableChars & """"
            End If
    
            If .CastString(sControlChars) Then
                For i = LBound(aintChars) To UBound(aintChars)
                    aintChars(i) = i
                Next
                Debug.Print """" & sControlChars & """"
            End If
        End With
    End Sub
    
    
    Attached Files Attached Files
    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)

  2. #2
    Hyperactive Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    296

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    This is a very useful class. I have a need to do the operation in reverse now.

    I have an Integer array which I want to convert to a string. I know that I can construct the string by looping through the integer array and converting each integer to a character. But I'm thinking that there's got to be a way to do it in one operation which is basically the mirror operation of the one which casts the string to an array.

  3. #3
    Hyperactive Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    296

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    Quote Originally Posted by AAraya View Post
    This is a very useful class. I have a need to do the operation in reverse now.

    I have an Integer array which I want to convert to a string. I know that I can construct the string by looping through the integer array and converting each integer to a character. But I'm thinking that there's got to be a way to do it in one operation which is basically the mirror operation of the one which casts the string to an array.
    I found the answer here:
    http://www.vbforums.com/showthread.p...=1#post5361253

  4. #4
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    285

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    Quote Originally Posted by AAraya View Post
    As I've demonstrated in that thread, there is no need for CopyMemory when there is an API function that does a better job. You mentioned above that you want a one-liner that performs the inverse operation—the SysReAllocStringLen function I've shown there is exactly what you're looking for.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,835

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    Or,

    Code:
    
    Option Explicit
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
    
    Private Sub Form_Load()
    
        Dim i() As Integer
        ReDim i(1 To 10)
    
        ' Give our i() array some values.
        Dim j As Long
        For j = LBound(i) To UBound(i)
            i(j) = 64 + j
        Next
    
    
        Dim s As String
        s = Space$(UBound(i) - LBound(i) + 1&)
        CopyMemory ByVal StrPtr(s), i(LBound(i)), (UBound(i) - LBound(i) + 1&) * 2& ' Copy UNICODE.
    
    
        Debug.Print s
    
    
    End Sub
    
    
    
    EDIT: Here it is as a little function:

    Code:
    
    Private Function StringFromIntArray(i() As Integer) As String
        StringFromIntArray = Space$(UBound(i) - LBound(i) + 1&)
        CopyMemory ByVal StrPtr(StringFromIntArray), i(LBound(i)), (UBound(i) - LBound(i) + 1&) * 2& ' Copy UNICODE.
    End Function
    
    
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    285

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    Quote Originally Posted by Elroy View Post
    EDIT: Here it is as a little function:
    That's basically the same as the one AAraya has linked to above, except that fafalone's version is using the slightly slower String$ instead of Space$.

    Code:
    Option Explicit
    
    Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
    
    Private Sub Form_Load()
        Dim i() As Integer
        Dim j   As Long
        Dim s   As String
    
        ReDim i(1 To 10)
    
        ' Give our i() array some values.
        For j = LBound(i) To UBound(i)
            i(j) = 64 + j
        Next
    
        #If SlowerAndMoreCode Then
    
        s = Space$(UBound(i) - LBound(i) + 1&)
        CopyMemory ByVal StrPtr(s), i(LBound(i)), (UBound(i) - LBound(i) + 1&) * 2& ' Copy UNICODE.
    
        #Else
    
        SysReAllocStringLen VarPtr(s), VarPtr(i(LBound(i))), UBound(i) - LBound(i) + 1&
    
        #End If
    
        Debug.Print """"; s; """"
    End Sub
    I really don't understand why people are so reluctant to use a demonstrably superior solution. Is it because they don't want to step out of their comfort zone (i.e., the oft-abused CopyMemory)?

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,835

    Re: [VB6] clsStrToIntArray.cls - Cast String To Integer Array

    Quote Originally Posted by Victor Bravo VI View Post
    I really don't understand why people are so reluctant to use a demonstrably superior solution.
    Victor, it's just what we're familiar with. I don't object at all to API calls, but I typically don't learn new ones until I'm forced to from some need or desire. In this case, there are fairly good solutions already available to us. *smiles and shrugs*
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

Tags for this Thread

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width