Announcement

Collapse
No announcement yet.

Redim an array by pointer?

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

  • Redim an array by pointer?

    I would like to use a pointer to redim an array like this test code:

    Code:
    Type xxttt
        h As Long
        Moreparams1 as long
        Moreparams2 as long
    End Type
    
    Function Test2( ByRef x As xxttt ) As Long
    
        Dim h() As Long At x.h
        ReDim Preserve h( 0 To 100 )
    
    End Function
    
    Function Test() As Long
    
        Dim h( 0 To 0 ) As Local Long
        Dim x As xxttt
        x.h = VarPtr( h() )    
        Test2( x )
    
        MsgBox Str$( UBound( h ) )
    
    End Function
    Usually i am using alternative code but i would like to do it this way if possible.
    hellobasic

  • #2
    I don't think so, but you could put the UBOUND of the array into the first element when you DIM it?

    BTW PRESERVE is not needed with DIM/REDIM AT.

    Comment


    • #3
      >BTW PRESERVE is not needed with DIM/REDIM AT

      More like, it has no meaning. When absolute arrays are used, the programmer is 100% responsible for the management of the underlying memory.

      Should probably be a compile-time error, "PRESERVE Option not allowed with DIM/REDIM 'AT' "

      Actually it should be a "warning only" but the compiler does not do warnings.. compilation has a binary solution set : pass/fail. But warning messages would be really cool.

      Edwin, if you want to REDIM an array in a procedure, just pass the whole array...
      Code:
         REDIM   Z(0) 
         CALL    SizeMyArray (Z(), other params) 
      
      FUNCTION SizeMyArray (X() AS something, other params) 
         REDIM [PRESERVE] X (value based on params) 
      END FUNCTION
      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        In fact it was for a callback.
        I had luck with BYREF as String so i thought a pointer to an array would do as well.
        I think it is possible but maybe not with dim at.

        Don't know..
        hellobasic

        Comment


        • #5
          Edwin I can't see what you are trying to accomplish with your function.

          If you want to resize the array in a separate procedure, just pass it...
          Code:
          FUNCTION Test2 (X() AS something) 
               REDIM X(100) 
          END FUNCTION 
          ....
          
          LOCAL h() AS LONG
          
           REDIM h( 0 To 0 )    ' just use REDIM, compiler can be weird with DIM
           Test2( h() )
          
            Print LBOUND and ubound of h() here, they will be 0 and 100.
          MCM
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Originally posted by Michael Mattias View Post
            Actually it should be a "warning only" but the compiler does not do warnings.. compilation has a binary solution set : pass/fail. But warning messages would be really cool.
            [/code]
            MCM
            *puts on a Red Hat*
            There are quite a few things I can think of that should have warnings, and warning messages doesn't exclude a pass/fail result. (Though I would prefer an exit code of 0-255 where 0 is full success and 1-255 represent any kind of compile/link/resource/whatever problems.) There should also be warning options (think of http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html ) I would also like to see a pragma to "escape" a single warning.
            Erich Schulman (KT4VOL/KTN4CA)
            Go Big Orange

            Comment


            • #7
              Originally posted by Michael Mattias View Post
              Edwin I can't see what you are trying to accomplish with your function.

              If you want to resize the array in a separate procedure, just pass it...
              Is what he wants to accomplish really important here? I mean, Edwin asked if An array could be redimmed using a pointer? Obviously he knows there are other ways to do it. After all, he is Edwin Knoppert, quite clearly neither a newby nor PB dummy.

              It seems to me the appropriate responses would be one (or combination) of "Yes, Eddie, and here's how ...", or "No Edwin, and here's why ..." or "Gee, Mr. Knoppert, I really don't know but could it be maybe done this way ...".
              It's a pretty day. I hope you enjoy it.

              Gösta

              JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
              LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

              Comment


              • #8
                I want to pass it to enumwindows() api for example.
                A string's varptr can be passed and in the callback obtained byref directly.
                This way i can reset the length or contents of the string fine.
                Though i am not able to do that using a type var.
                The type var is passed the same but the array's varptr resides in the type var and is not passed as lparam.
                hellobasic

                Comment


                • #9
                  >Edwin asked if An array could be redimmed using a pointer?

                  The answer is "yes," if that pointer is to the array descriptor.

                  Then he pointed out ...
                  >I want to pass it to enumwindows() api for example

                  So, you pass the address of the array descriptor by defining your callback function thus....
                  Code:
                  FUNCTION CallbackProc (BYVAL Hwnd AS LONG, X() AS SomeType) AS LONG
                  ... and calling the Enum function with your lparam/dwUser value = VARPTR(Array()) (with the empty parens)


                  No muss, no fuss, no bother.

                  MCM
                  Last edited by Michael Mattias; 6 Nov 2008, 09:56 AM.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    It can be done, but you haven't allocated the necessary memory (and PB doesn't allocate it in DIM AT), it may GPF.
                    Code:
                    #COMPILE EXE
                    #DIM ALL
                    
                    TYPE xxttt
                        h AS LONG
                        Moreparams1 AS LONG
                        Moreparams2 AS LONG
                    END TYPE
                    
                    FUNCTION PBMAIN () AS LONG
                    
                        DIM h( 0 ) AS LOCAL LONG    'dimension to max needed size, eg. here it would need to be h(100)
                        DIM x AS xxttt
                        x.h = VARPTR( h() )
                        Test2( x, h() )             'If the array h() is not passed, Test2 creates a 2nd different array entirely.
                        
                        ? STR$(h(0))
                        ? STR$(h(1))                'unallocated memory, possible GPF. To solve problem, dimension h() above to
                        ? STR$(h(100))              'the max needed size, eg. 100
                        MSGBOX STR$( UBOUND( h ) )
                    
                    END FUNCTION
                    
                    FUNCTION Test2( BYREF x AS xxttt, h() AS LONG ) AS LONG
                    
                    '   Dim h() As Long At x.h
                    '   REDIM PRESERVE h( 0 TO 100 ) AS LONG    '<this will no longer be at x.h
                    '   So to keep the array at x.h, the above can be done in one statement:
                        REDIM h( 0 TO 100 ) AS LONG AT x.h 'this will however, be dimensioning into unallocated memory. Could GPF.
                    
                    END FUNCTION

                    Comment


                    • #11
                      What about some dynamic string fake buffers and some dummy DIM ... AT ?
                      Graet flexibility, great power.

                      Code:
                      Type xxttt
                        MyArray1 As Long
                        MyArray2 As Long
                        '...
                      End Type
                      Function Allocate_My_X( ByRef x As xxttt ) As Long
                        '---Allocate room for 100 LONG: 100 * sizeof(LONG)
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray1)
                        DummyString(1&) = Repeat$(100 * 4, $Nul)
                        
                        ReDim DummyLong(1& To 100&) As Long At VarPtr(x.MyArray1)
                        '---Do whatever with DummyLong
                        
                        '---Allocate room for 100 EXT: 100 * sizeof(EXT)
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray2)
                        DummyString(1&) = Repeat$(100 * 10, $Nul)
                        ReDim DummyExt(1& To 100&) As Ext At VarPtr(x.MyArray2)
                        '---Do whatever with DummyLong
                      End Function
                      Function Free_My_X( ByRef x As xxttt ) As Long
                        '---Remove
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray1)
                        Reset DummyString(1&)
                        
                        '---Remove
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray2)
                        Reset DummyString(1&)
                      End Function
                      Function ReDim_My_X( ByRef x As xxttt ) As Long
                        
                        '---Add 150 LONG numbers
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray1)
                        DummyString(1&) += Repeat$(150 * 4, $Nul)
                        
                        '---Add 350 EXT number
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray2)
                        DummyString(1&) += Repeat$(350 * 10, $Nul)
                      End Function
                      Function Use_My_X( ByRef x As xxttt ) As Long 
                        Local nItems As Long
                        
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray1)
                        nItems = Len(DummyString(1&))/4
                        ReDim DummyLong(1& To nItems) As Long At VarPtr(x.MyArray1)
                        '---Do whatever with DummyLong
                        MsgBox "My array of LONGs has" & Str$(UBound(DummyLong)) & " elements"
                          
                      
                        ReDim DummyString(1& To 1&) As String At VarPtr(x.MyArray2)
                        nItems = Len(DummyString(1&))/10
                        ReDim DummyExt(1& To nItems) As Ext At VarPtr(x.MyArray2)
                        '---Do whatever with DummyLong
                        MsgBox "My array of EXTs has" & Str$(UBound(DummyExt)) & " elements"
                      End Function
                      
                      Function PBMain() As Long
                          Dim x As xxttt
                          Allocate_My_X ( x )
                          Use_My_X      ( x )
                          MsgBox "Now making some redim ..."
                          ReDim_My_X    ( X )
                          Use_My_X      ( x )
                          Free_My_X     ( x )
                      End Function

                      Comment


                      • #12
                        Call me set in my ways, but setting up the callback to have a parameter of "MyArray() AS MyType" sure seems the easiest way.

                        When you do this you may use any array functions you want - including REDIM [PRESERVE] - without doing anything else anywhere.
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          Haven't you seen the other params?!!
                          hellobasic

                          Comment


                          • #14
                            >Haven't you seen the other params?!!

                            Code not shown.

                            You said you wanted to pass the array to EnumWIndows and REDIM it there. I did that.

                            You want more params, pass 'em as additional members of MyArray().

                            Or, I suppose you can contact my office for a quotation.
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Gee, can't find the terminate thread button..
                              hellobasic

                              Comment

                              Working...
                              X