Shop OBEX P1 Docs P2 Docs Learn Events
Arrays as a Parameter — Parallax Forums

Arrays as a Parameter

kt88seampkt88seamp Posts: 112
edited 2010-05-02 00:26 in Propeller 1
Is there a way to pass an array as a parameter between methods? If not a pointer?

Comments

  • RaymanRayman Posts: 14,887
    edited 2010-05-01 01:41
    Yes, it's easy to pass an address to any data structure using the @ language element...

    Several of the example apps do this...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm

    My Prop Products:· http://www.rayslogic.com/Propeller/Products/Products.htm
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-05-01 09:33
    So, the answer to the question is no!

    THE ONLY THING YOU CAN PASS AS PARAMETER IS A LONG! (or more)

    What the long means can be different. Sometimes it's a byte value or a word value or a long value. You can also interpret it as a 4 byte array, you can interpret it as a 2 word array .. you can use it as a 2 byte 1 word 'container'.
    If you have bigger data structures there is no other way than passing the address to that data structure. Which by the way is far more efficient, because each parameter is pushed to the stack. This needs additional memory plus runtime.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-05-01 15:19
    ... and a LONG can hold the address of any data element, even an array. I think the point MagIO2 is trying to make is that the receiving method needs to know the elemental type of the array, otherwise you could have problems.

    As a trivial example, this method can sums the first n elements of the array passed to it; it assumes the array is of bytes.

    pub sumarray(ptr, n) | sum
    
      sum~
      repeat n 
        sum += byte[noparse][[/noparse]ptr++]
        
      return sum
    


    Let's say you have a 10-element array of bytes and you want to know the sum of the first five elements, you can call the above method like this:

    x := sumarray(@readings, 5)
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA

    Post Edited (JonnyMac) : 5/1/2010 3:26:41 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-05-01 16:43
    What I wanted to say is:

    1. It's easy ... a parameter is a LONG - period.
    2. Whatever fits into a long can be passed directly. Up to 4 bytes, up to 2 words, 1 long. Whatever they contain.
    3. AND yes, Jonny, both sides have to know what a parameter contains/has to contain
    Basically there are only 2 posibilities: either the parameter contains a value or an address.

    If you use an object you need to know what the content of a function parameter has to be - an address or a value. Otherwise the function won't work as expected. If the function returns a value the caller needs to know what that function will return, a value or an address.

    For example:
    - a:=string( "jlkjj" ) is a function buildin the SPIN compiler, but it will "give back" an address to the string.
    - num.tostr( 10 ) is a function which expects a long and it returns an address to the converted string.
    - strsize( @a ) is a function expecting a string address and gives back a long

    But that's only the easy part ;o) I tend to squeeze out any byte of a parameter/return value. Which means I often use one parameter to pass several values or a mixture of pointer and value .....
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-05-01 18:39
    @kt88.. How many and how big are the parameters you want to pass?
    Are they passing between cog's?
    If not, you can just define the array in the 'VAR' section of your code and it will be accessable to all of the PUB/PRI code in the block.
    J-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-05-01 18:39
    @kt88.. How many and how big are the parameters you want to pass?
    Are they passing between cog's?
    If not, you can just define the array in the 'VAR' section of your code and it will be accessable to all of the PUB/PRI code in the block.
    J-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • kt88seampkt88seamp Posts: 112
    edited 2010-05-01 21:46
    I am doing this:

    
    PUB Main | DataBytes
    
    DataByte[noparse][[/noparse]0] := 45
    DataByte := 67
    DataByte := 89
    DataByte := 34
    
    TXArray(@DataBytes)
    
    PUB TXArray(DataBytes) | i
    
    repeat i from 0 to 3
         SER.TX(DataBytes[i])
    
    [/i]
    



    I am passing the array to the transmit method with a pointer. Is the best way? It is definitely the easiest.
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-05-01 22:45
    The effencies of different methods would depend on how many bytes you want to send·total. If it's more than 4 bytes, sending a pointer is definitely the fastest way to do it.

    How many bytes total·are in the array?

    J-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • kt88seampkt88seamp Posts: 112
    edited 2010-05-01 22:50
    16 bytes.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-05-02 00:26
    Wow ... that's bad.

    Is the [noparse][[/noparse] ] missing in the definition of DataBytes (behind the main)? If not, DataBytes would only be one long and your assignments will overwrite some memory that does not belong to DataBytes. If it's in the main COG you have a good chance that nothing will happen, but if you do this in a function called by COGNEW and the stack is just big enough for some parameters / local variables, you have a good chance to overwrite some important stuff.

    Now let's assume that your DataByte only has to store bytes. You should not create that variable as a local variable, as these are always LONGs. Better put the DataByte to the VAR section in this case, really using bytes.

    VAR
    byte DataBytes[noparse][[/noparse] 16 ]

    If your DataBytes are constant, then you can also think of creating DataBytes in a DAT section, because there the assignment is for free (no extra menory, no extra runtime):

    DAT
    DataBytes byte 45, 67, 89, 34, ....

    In transmit array you don't want to send the address of the array, do you? You want to send the bytes in the buffer, so you have to get the values from that address:

    PUB transmit( dataBytes_adr )
    repeat i from 0 to 3
    SER.TX( byte[noparse][[/noparse]dataBytes_adr]

    It's a good idea to give a hint of the content of a variable by using a good name. _adr means that this variable only contains an address to a variable.
Sign In or Register to comment.