Announcement

Collapse
No announcement yet.

Whats in a string handle?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Whats in a string handle?

    Hello,

    Could someone clear up how string handles work?

    I know this much, the string handle is a pointer to another
    pointer that points to the real string data.

    Code:
    dim handle as long
    dim pointer as byte ptr
    
    handle = varptr(string)
    pointer = handle
    @pointer = (first byte in string)

    so what is the handle, I thought that maybe it could be a handle
    returned by GlobalAlloc() but that did not seem to be the case as
    the following example returns zero.

    Code:
    dim buff as string
    
    buff = "This is a test message" 
    msgbox format$( GlobalSize( varptr(buff) ) )



    ------------------
    Cheers

  • #2
    I do not know of any uses for dynamic string handles. They are
    sort of an internal PB thing that we should not really be
    messing with.

    Don't use VARPTR with dynamic strings, only use VARPTR with
    fixed sized strings and ASCIIZ strings.

    If you want to use pointers to get to dynamic string data use
    STRPTR to get the address of the data and ignore the handle that
    VARPTR returns to you.

    Dim string1
    Dim pointer as byte ptr
    string1 = "Hi Mom!"
    pointer = STRPTR(string1)
    @pointer = (first byte in string)
    @pointer[0] = (first byte in string)
    @pointer[1] = (second byte in string)


    Tim




    ------------------

    Comment


    • #3
      A dynamic string handle is most important internally to PowerBASIC, and is used so that PB can track, allocate and deallocate memory for the actual string data itself (which is located elsewhere in memory). These handles are also used when dealing with the Windows OLE string engine.

      Additionally, the address of scalar string handles stays consistent (within the scope of the string) although the actual string data will change memory location with each assignment. Handles of strings in dynamic string arrays only move when the array is REDIMed. The address of handles to LOCAL strings and arrays are deallocated when the owning Sub/Function terminates.

      Using the VARPTR value of a dynamic string (ie, the address of the actual handle), you can use a string pointer interchangably with actual strings, for example:
      Code:
      ' Pseudocode
      DIM a$, b$, pa AS STRING POINTER, pb AS STRING POINTER
      a$ = "Hello"
      pa = VARPTR(a$)
      b$ = @pa & " world!"
      pb = VARPTR(b$)
      MSGBOX @pa & $CRLF & @pb
      Tim, please note that POINTER is a synonym of PTR.


      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Hello...


        The reason I was looking into this was because I wanted to use
        the "get$" with a string pointer to an array. This would mean
        we could load very large files into memory without having to
        allocate twice the amount of memory, once for the array and
        another for the string.


        Code:
        function GetRecord(byval Length as long,byval Record as long) as long
            dim Buffer as string ptr
        
            Buffer = Record 'set buffer pointer to record pointer'
            get$ #1,Length,@Buffer 'read string into -> Record via string
        end function
        Record = varptr(summary)
        Length = len(summary)

        or

        Record = varptr(mudrecord)
        Length = len(mudrecord)


        It's really silly to allocate twice the amount of memory you need
        and also have to "memcopy" half a block over to the other when loading
        files into memory. I know I could use the windows API but in all honesty
        it just becomes very ugly.



        ------------------
        Cheers

        Comment


        • #5
          There is most likely a better way to do this, but this the
          the way I do it. The disk read takes around 1000 times more
          time than diming and clearing the buffer string, so I
          found no point at all in trying to make it any faster.


          i1PTR = VARPTR(xSort(1)) '// The first element of the array
          sBUFF = STRING$(40000, 0)
          GET #1, 1, sBUFF 'xSort
          POKE$ i1PTR, sBUFF
          sBUFF = ""

          Tim


          ------------------

          Comment


          • #6
            If you use the ReadFile() API, you can just pass the
            address to place the number of bytes read.
            Use FileAttr() to get the HANDLE of the open file then ReadFile()
            to read the data into memory at the specified starting address.





            ------------------
            Ron

            Comment


            • #7
              Ron, I must be missing something here... what is the advantage of using the API directly over using the native GET$ statement as suggested in the previous message?

              GET$ takes care of a lot of the details of memory allocation and file I/O for you, but using the API technique means a lot more lines of code to do the exact same job. Where is the gain?



              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                Mark,

                I don't properly know what the array type is that you are using but if it
                is a linear array such as a numeric type LONG, INTEGER etc ... and not a
                STRING array, you can DIM the array you want at the address of the string
                that you load from disk.

                This test piece that follows tests a string full of zeros that has an
                array redimmed at the same address as the string so if you load the string
                with GET$, this method may do the job for you.

                The method Ron outlined will do the job for you as it can specify the
                address of the buffer to load it into which in your case is the array and
                this is the advantage of the API approach but it is more code to write to
                get it going.

                Regards,

                [email protected]

                Code:
                  '##########################################################################
                  
                  FUNCTION TestArray() as LONG
                  
                      LOCAL src as LONG
                  
                      a$ = string$(24,chr$(0))        ' 24 bytes of zeros.
                  
                      src = StrPtr(a$)
                  
                      redim var(5) as LONG At src     ' 6 member LONG array = 24 bytes
                  
                      MsgBox hex$(var(0))
                  
                      FUNCTION = 0
                  
                  END FUNCTION
                  
                  '##########################################################################
                ------------------
                hutch at movsd dot com
                The MASM Forum

                www.masm32.com

                Comment

                Working...
                X