Announcement

Collapse
No announcement yet.

Redim an array by pointer?

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

  • Edwin Knoppert
    replied
    Gee, can't find the terminate thread button..

    Leave a comment:


  • Michael Mattias
    replied
    >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.

    Leave a comment:


  • Edwin Knoppert
    replied
    Haven't you seen the other params?!!

    Leave a comment:


  • Michael Mattias
    replied
    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.

    Leave a comment:


  • Eros Olmi
    replied
    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

    Leave a comment:


  • John Gleason
    replied
    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

    Leave a comment:


  • Michael Mattias
    replied
    >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, 10:56 AM.

    Leave a comment:


  • Edwin Knoppert
    replied
    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.

    Leave a comment:


  • Gösta H. Lovgren-2
    replied
    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 ...".

    Leave a comment:


  • Erich Schulman
    replied
    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.

    Leave a comment:


  • Michael Mattias
    replied
    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

    Leave a comment:


  • Edwin Knoppert
    replied
    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..

    Leave a comment:


  • Michael Mattias
    replied
    >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

    Leave a comment:


  • Chris Holbrook
    replied
    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.

    Leave a comment:


  • Edwin Knoppert
    started a topic Redim an array by pointer?

    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.
Working...
X