Announcement

Collapse
No announcement yet.

passing dynamic string arrays

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

  • passing dynamic string arrays

    I want to pass an array address to a function which populates the array with up to m rows (max of m is known) of n columns (max of n is not known, though there is a limit to the combined length of all ns in a row). It's easy to pass a one-dimensional string array pointer and populate the array, which takes care of m, but how does one copy the entire array into a string and then extract it again? The nature of the data precludes the use of substring delimiters, and because n is unknown to the calling procedure it is not possible to REDIM the passed array to fit.

    Looking at GET# and PUT# help, it appears possible that the string could be stored in one of two different formats. Also, do dynamic string arrays always occupy contiguous storage? If so, just a length function would be enough. But LEN() does not appear to work either with arrays or with string pointers.

    Sure I've read something on this but I can't find it again, about time the topical index facility was added to these forums!

  • #2
    ??

    Why not just pass the entire array and resize it in the load function?
    Code:
    FUNCTION Populate (S() AS STRING) AS LONG
    
       REDIM S (m,n) 
       Populate...
    
    END FUNCTION
    
    ...
        REDIM X(0,0) AS STRING
        CALL  Populate (X()) 
        nRow =    UBOUND (X,1) + 1     ' assuming populated from (0,0) 
        nColumn = UBOUND (X,2) + 1
    ???

    Yes, string arrays like all arrays in memory use contiguous memory for the string handles (32-bit values), although the string data itself might be 'anywhere'

    When a string array is saved to disk, it's not saved that way; that's a whole 'nother thing.

    Both memory and disk storage formats are described in the help file.

    LEN() works just fine with arrays and STRING PTRs. Show failing code.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Originally posted by Michael Mattias View Post
      Why not just pass the entire array and resize it in the load function?
      You mean just like this? It seems to work...

      Code:
      #COMPILE EXE
      #DIM ALL
      #INCLUDE "WIN32API.INC"
      %IDD_DIALOG1  =  101
      %IDC_LISTBOX1 = 1001
      %IDC_LABEL1   = 1002
      '------------------------------------------------------------------
      SUB poparray( s() AS STRING)
          LOCAL i, j, n, m AS LONG
      
          n = RND(1,10)
          m = RND(3, 9)
          
          REDIM s( 0 TO m, 0 TO n) AS STRING
          FOR i = 0 TO m
              FOR j = 0 TO n
                  s(i, j) = STR$(i* (j^2) + j)
              NEXT
              s(i,0) = STR$(i)
          NEXT
      END SUB
      '------------------------------------------------------------------
      CALLBACK FUNCTION ShowDIALOG1Proc()
          LOCAL i, j AS LONG
          LOCAL sarray() AS STRING
          LOCAL s AS STRING
      
          SELECT CASE AS LONG CBMSG
              CASE %WM_INITDIALOG
                  GOSUB test
              CASE %WM_COMMAND
                  SELECT CASE AS LONG CBCTL
                      CASE %IDC_LISTBOX1
                          RANDOMIZE
                          LISTBOX RESET CBHNDL, %IDC_LISTBOX1
                          GOSUB test
                  END SELECT
          END SELECT
          EXIT FUNCTION
      test:
          REDIM sarray(0 TO 0) AS STRING
          poparray( sarray())
          FOR i = LBOUND(sarray, 1) TO UBOUND(sarray, 1)
              s = ""
              FOR j = LBOUND(sarray, 2) TO UBOUND(sarray, 2)
                  s = s + "," + sarray(i, j)
              NEXT
              LISTBOX ADD CBHNDL, %idc_listbox1, MID$(s, 2)
          NEXT
          RETURN
      END FUNCTION
      '------------------------------------------------------------------
      
      FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
          LOCAL lRslt AS LONG
          LOCAL hDlg  AS DWORD
      
          DIALOG NEW hParent, "pop string array of unknown dimensions", 155, 116, 270, 140, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _
              %WS_SYSMENU OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
              %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
          CONTROL ADD LISTBOX, hDlg, %IDC_LISTBOX1, , 5, 5, 260, 110, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR _
              %LBS_NOTIFY, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
          CONTROL ADD LABEL, hDlg, %IDC_LABEL1, "click on the listbox data to refresh", 5, 118, 160, 15
          DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
          FUNCTION = lRslt
      END FUNCTION
      '===================================================
      FUNCTION PBMAIN()
          ShowDIALOG1 %HWND_DESKTOP
      END FUNCTION

      Comment


      • #4
        I've been doing that literally for years for "load" functions. It makes it really easy to change "how much" stuff gets loaded.

        Also, it's how I discovered the incompatibility between PB 6x- and 7x+ array descriptors. My 7x program failed to load something using a function from a 6x DLL.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment

        Working...
        X
        😀
        🥰
        🤢
        😎
        😡
        👍
        👎