Announcement

Collapse
No announcement yet.

What API to use to make PB string compatible dynamic string?

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

  • Tom Hanlin
    replied
    The SysAlloc APIs are specialized versions of the more generic memory APIs,
    so I'd speculate they might be slower. Probably, it doesn't make a great
    deal of difference but, when in doubt, try it out.

    I don't mean to recommend HeapAlloc in particular. Windows offers a variety
    of memory APIs. You might search for some of the previous messages on this
    subject.


    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Edwin Knoppert
    replied
    Btw Tom,

    Can you recommend SysAlloc.. above the GetProcessHeap()/HeapAlloc combination?

    I expect SysAlloc to be faster.
    Then i would prob. use peek$ to access it..

    Thanks,


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Edwin Knoppert
    replied
    Tom,

    I'll reconsider..

    Thanks,


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Tom Hanlin
    replied
    Variable-length strings are inherently inefficient in numerous respects, and it's
    really not a good plan to try to fool the compiler into thinking your strings are
    its strings. This approach does not seem appropriate to the task at hand.

    It would almost certainly be safer, faster, and easier if you just did it using
    BYTE pointers with HeapAlloc, and wrote your own byte-based search routine to
    replace the former use of INSTR.

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Edwin Knoppert
    replied
    Wow!

    Misread that one completely!!

    Thanks,



    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Florent Heyworth
    replied
    Hi Edwin

    you should use SysAllocStringByteLen not SysAllocStringLen
    which is unicode and use SysStringLen() although you'll
    probably be okay if you use LEN()

    Cheers

    Florent

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

    Leave a comment:


  • Edwin Knoppert
    replied
    Thanks,

    The freeing was just an example, i declared it wrong anyway.
    Let's forget that one..

    The following code becomes importaint to me.
    See the original length, it's 2x the size.

    Just don't understand this part.

    Code:
    #Compile Exe
    #include "win32api.inc"
     
    Function WinMain( ByVal hCurInstance  As Long, _
                      ByVal hPrevInstance As Long, _
                      lpszCmdLine         As Asciiz Ptr, _
                      ByVal nCmdShow      As Long ) As Long
     
     
        Dim sData   As String
        Dim pAddr   As Long Ptr
        Dim Lng     As Long
        Dim T       As String Ptr
     
        sData = Repeat$( 1, "12345678" )
        pAddr = SysAllocStringLen( ByVal StrPtr( sData ), Len( sData ) )
     
        '// Seems to be a must..
        Lng = pAddr
        T = VarPtr( Lng )
     
     
        '// Check length of SysAllocStringLen() and original Len of sData..
     
        MsgBox Format$( Len( @T ) ) & ", " & Format$( Len( sData ) ) & $CRLF _
            & "'" & @T & "'"
     
     
        '// Refill using PB..
        @T = "1234"
     
     
        '// Check out lengths again..
        MsgBox Format$( Len( @T ) ) & ", '" & @T & "'"
     
     
     
     
     
        SysFreeString ByVal pAddr
     
    End Function
    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Florent Heyworth
    replied
    SysAllocStringByteLen is not Unicode...

    In order to check that a string has been effectively
    freed you should check GetLastError() after each call
    to SysFreeString() - a non-zeo return value indicates
    an error. Use SysStringLen() to find the length of the
    string.

    It's my understanding that strings freed are marked for
    deletion but not immediately freed (they are "lazily" collected).

    You're asking for trouble when addressing freed strings although
    the trouble may not be immediately apparent. Set the string
    pointer to NULL after freeing it - it'll help to avoid
    errors.

    Cheers

    Florent





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

    Leave a comment:


  • Edwin Knoppert
    replied
    Already found out that this writes in the wrong mem
    Don't use it..

    The SysAlloc.. calls are unicode, PB doen't seem to use it that way.
    There is a conflict in string length that way.
    The original API declare will take 2x the size.
    A string pointer set will show this until you use the string poiter to set new data.
    Then Len() will work ok.
    It becomes a bit weird now.

    It certainly would help me if i get this to work.


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Edwin Knoppert
    replied
    Semen,
    This is the way we use it.
    At the end it get's to much items, the search becomes to slow.
    We use objectnames (e.g. "TEXT1") to find the data.

    PB:

    Can i use the code below,
    It seems the String ptr creates it's own memory address.
    However, i don't know when or how to destroy the memory.
    There should be a crash in the following code but does not.

    Code:
    #Compile Exe
    #include "win32api.inc"
     
    Function WinMain( ByVal hCurInstance  As Long, _
                      ByVal hPrevInstance As Long, _
                      lpszCmdLine         As Asciiz Ptr, _
                      ByVal nCmdShow      As Long ) As Long
     
     
        Dim L As Long
        Dim T As String Ptr
     
        L = VarPtr( L )
        T = L
     
        @T = "1345sdfyghbfghn"
     
    '??????????????????????
    
        SysFreeString ByVal L
        SysFreeString L
        SysFreeString ByVal T
        SysFreeString ByVal VarPtr( @T )
     
        MsgBox @T
     
    End Function
    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Semen Matusovski
    replied
    Edwin --
    What about this organization of multidimensional array (w/o API) ?
    Code:
       #Compile Exe
       #Dim All
       #Register  None
       #Include "WIN32API.INC"
       
       Function PbMain
          ' %n - maximum strings in all files
          %n =   5
          %nf =  3  ' maximum records in one file
         
          Dim s(%n - 1) As String ' Strings
          Dim r(%n - 1) As Long   ' File id
          Dim v(%nf - 1) As Long  ' for VarPtr
         
          '============== Fill strings =============
         
          s(0) = "File 1, Record 1" : r(0) = 1
          s(1) = "File 2, Record 1" : r(1) = 2
          s(2) = "File 1, Record 2" : r(2) = 1
          s(3) = "File 1, Record 3" : r(3) = 1
          s(4) = "File 2, Record 2" : r(4) = 2
         
          '============ Create "array" from single file ====
          Dim i As Long, k As Long, f As Long
           
          For f = 1 To 2
             k = 0
             For i = 0 To %n - 1
                If r(i) = f Then v(k) = StrPtr(s(i)): Incr k
             Next
         
             If k > 0 Then
                ReDim ss(k - 1) As String At VarPtr(v(0))
                For i = 0 To k - 1
                   MsgBox ss(i),, "Array" + Str$(f)
                Next
             End If
          Next
       End Function
    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Edwin Knoppert
    replied
    For situation 1 we have a single array where we use array scan.
    This array is a simple long containing a crc of another dynamic string array containing the real name of the object.
    The CRC is found in the 'long' array and it checks the requested objecname.
    this is because the CRC can be added multiple times plus in this older situation, the file index needs to be check too.

    The older system handles multiple files in 'one' array (where at the end 4 arrays are used to manage this all)

    Complex?

    I can do this with api but then i need peek and poke what i dislike.


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Edwin Knoppert
    replied
    1) I need a multidimensional array where the second array must be flexible
    2) I need a multidimensional String array where the second array must be flexible

    Let's speak about situation 2 only:

    Global Files() As String

    (f = 1 to nn, depends on opened files)
    x = nn objects for that file
    this can be less or more than in Files( 2...

    ReDim Files( 1 to f, 1 To x )

    Since this is not possible i'm gonna use API's

    A heapalloc to allocate a string ptr array to solve the Files( 1 to f, part
    The address will be stored in a single array.

    The data should be a dynamic string
    It's length is variable per element (1 byte to 200k etc..)
    I wanted to use a string ptr to explore the memory address using instr etc..
    So i would have to copy the data over and over.
    This is a time critical procedure and must be very fast.
    We already have it running where all 'files' are stored in 1 string array.
    After 10000 objects the search is slow.
    10000 objects is fine but not if multiple files are adding another 10000 objects to it.
    We need to break it up.
    (PS, there's no way i rewrite these file systems, it's implemented for 1000's of users already.)

    This is a weird situation because of the dynamic range required for the second entry of the m. array.



    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Tom Hanlin
    replied
    As has been pointed out, PB uses SysAllocStringByteLen in creating strings.
    However, as usual, it's (1) a bad idea to try to fool the compiler, and (2)
    you don't generally gain anything by trying.

    It sounds to me like your best bet here is to PEEK$ and POKE$ the data. If
    you would like to explain what you need to do in more detail, though,
    perhaps a better solution will offer itself.

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Edwin Knoppert
    replied
    Semen,

    I have not planned to use any PB code to redim the original contents.
    This will be API/OLE too.

    The memory will be destroyed and rebuild.


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Edwin Knoppert
    replied
    i REALLY want the PB strings.
    Wich API/Method is PB using.
    I simply can use my memory using HeapAlloc etc and add 4 bytes (long ) before the string data to simulate the OLE strings.
    This is NOT safe for future windows versions.

    I really need the original PB calls so that String Ptr can be used on them.

    Jules, if i check the PB EXE's, i see the SysAllocStringByteLen() api calls.
    I need confirmation on that.

    In this case i need to create my own memory, for using it i would like to use PB's string pointer.
    Peek$() will be my last resort.


    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Semen Matusovski
    replied
    It's not a problem to fool PB, if to use OLE functions (PB does the same).
    Code:
       #Compile Exe
       #Dim All
       #Register  None
       #Include "WIN32API.INC"
    
       Function PbMain
          ' Step 1 - Create Strings
          Dim x(2) As Local Long
          x(0) = SysAllocStringByteLen("Compile", 7)
          x(1) = SysAllocStringByteLen("Compile Exe", 11)
          x(2) = SysAllocStringByteLen("Dim", 3)
          
          ' Let's fool Pb
          ReDim s(2) As String At VarPtr(x(0))
          MsgBox s(0) + $CRLF + s(1) + $CRLF + s(2)
          
    End Function
    But it seems to me that Edwin means that he do not use OLE API to create strings.
    Of course, it's possible to create in memory OLE-similar strings (length of string, string as it is, zero).
    But I am afraid re-allocate statements (a$ = ...)


    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Jules Marchildon
    replied
    Edwin,

    Look into these API's functions, they were handed to me by Florent Heyworth,
    they are very interesting functions.
    Code:
    SysAllocStringByteLen()
    SysFreeString()
    HTH
    Regards,
    Jules

    Leave a comment:


  • Michael Mattias
    replied
    Well, if you want dynamic (variable length) strings, you will not be able to specify the address of the string data except by POKEing the data where you want it..

    Your best bet might be what you've started - an array of STRING PTR which you create at a specific memory location with DIM AT.

    What I do not understand is what API call returns an address but does not handle the allocation of the memory?

    Which API call is this?

    MCM

    Leave a comment:


  • What API to use to make PB string compatible dynamic string?

    I need to use the API (i think) to create a dynamic string but the address is fixed.

    The memory area is created by a specific api call, an array with String ptrs will be used to access these strings.
    I can not use asciiz.

    Code:
    Global MyArray() As String Ptr
    
    ''''
    
    Redim MyArray( 1 to 1000 )
    Dim pAddr As Dword
    
    pAddr = >> this is the problem, Malloc or sort of, don't know exactly..
    
    MyArray( 1 ) = pAddr
    
    Dim PBString As String At MyArray( 1 )
    (Or string ptr if necessary)
    
    Msgbox PBString

    ------------------
    http://www.hellobasic.com
Working...
X