hexagon logo

How to pass a virtual string array to a function?

I've defined a PCL function called "find_elem_id" which is called by another function. I'm passing an integer and a string array (VIRTUAL) in size to this function, and I'm getting this runtime error:
 
$# ===(PCL) Invalid data range for argument. Arg#: 2
$# ===Call traceback...
$#     Function SYS_ALLOCATE_ARRAY
$#     Function FIND_ELEM_ID, Line Number 837
 
I believe it is being caused by how I'm passing the string VIRTUAL array to the find_elem_id function (see below).
 
I tried defining the variable as strFoundGroups[32]() inside the find_elem_id function but that didn't help.
 
Can anyone see what I'm doing wrong?
 
Thanks.
 
STRING strFoundGroups[32](VIRTUAL)
find_elem_id (100,strFoundGroups)
 
$# ======================================================
FUNCTION find_elem_id ( intElementID, strFoundGroups )
 
 INTEGER intElementID
 STRING strFoundGroups[]()  $# <<--- this is causing a runtime error
 
 (do stuff here)
 
END FUNCTION
  • Dave,
    In general, your declaration in function find_elem_id() is correct:
    STRING strFoundGroups[]() 
     
    Are you sure it's an array allocation problem?
    When I tried to replicate your example, I get a run-time error on the call to find_elem_id (). I had to include the class name (eg class.function().
    See my expanded example below.
    Also, a note about comments. Avoid the $ style and stick to /* */.
    You will avoid headaches in the long run.
     
    CLASS for_davef
    FUNCTION start_here()
     
    STRING strFoundGroups[32](VIRTUAL)
    for_davef.find_elem_id (100,strFoundGroups)
     
    END FUNCTION
    /* ============= end of start_here ======================== */
     
    FUNCTION find_elem_id ( intElementID, strFoundGroups )
     
     INTEGER intElementID
     STRING strFoundGroups[]() /* <--- this does not cause a runtime error */
     INTEGER my_size
     sys_allocate_array(strFoundGroups, 1, 5)
     
     my_size = sys_array_hbound(strFoundGroups, 1)
     DUMP my_size
     
    END FUNCTION
    /* =============== end of find_elem_id ===================== */
    END CLASS
  • Hey, Ken.
     
    Thanks for the response. No, I'm not sure what the problem is. I get this error message,
     
    ===(PCL) Invalid data range for argument. Arg#: 2
    $# ===Call traceback...
    $#     Function SYS_ALLOCATE_ARRAY
     
    Even when I use this function:
     
    function find_elem_id ( intElementID, strFoundGroups )
       integer intElementID   
       STRING strFoundGroups[]()   
    end function​
     
    So, I'm not sure why I'm getting the invalid data range for Arg #2 error message when I call this find_elem_id() function. My function doesn't call the SYS_ALLOCATE_ARRAY() function, so I was assuming Patran was calling the sys_allocate_array() function as it entered my function. Any tips on how to diagnose this issue?
     
    Thanks.
  • Eventually a virtual array has to be allocated (by your code, or Patran).
    Patran will do it ONLY IF it's an input to a function that expects a virtual array (string or otherwise). If not, you need to allocate. That said, you can pass a virtual array and allocate in your function. Many intrinsic functions do this.
     
    Did you try to compile and run my example?
    It's self contained, so should work for you. I pass a virtual string array, allocate the array, and was able to interrogate the size (printed at the end).
     
    How to debug?- the old fashioned way? :)
    Good luck.
  • Thanks again, Ken. I guess some things don't change. I'll give it a go again tomorrow.
     
    Take care.​
  • Hi Dave,
    just as a possibility:
    I would look carefully at the array size values you are using with the sys_alocate_array call.
    To my reading of it the error message is saying that the lower value of the array dimension is not valid. However the message also appears if argument 3 is not valid in relation to 2. This typically happens when you do not have an error trap for the case where the number of items is zero and you do a call like:
     
    sys_allocate_array(strFoundGroups,1,inum)
    if inum is zero then you get :
     
    sys_allocate_array(strFoundGroups,1,0)
    $# ===(PCL) Invalid data range for argument. Arg#: 2
    $# ===Call traceback...
    $#   Function SYS_ALLOCATE_ARRAY
     
    one workaround for this type of issue is to use:
    sys_allocate_array(strFoundGroups,1,max(inum,1))
     
    this should not fail and then when your doing a loop around inum, you ensure that it does nothing if inum=0
     
    of course there are other solutions to this but the important thing is to avoid calling sys_allocate_array where you specify an upper bound that is lower than the lower bound.
     
     
    apologies if this is not the issue .
    Arthur
  • ​Ok, mystery solved! I figured out why I'm having this problem.
     
    I've written several utilities for Patran that are compiled and stored in a plb file, which I then install whenever Patran starts up. I access these utilities from a custom dropdown menu in Patran.
     
    When I write a new utility, I often use a previous PCL code file as a template and modify it. Apparently, I have a function from a different installed utility named df_elem_id() which has the same name as the function I'm trying to call in my current utility. So when I run my new utility code, it seems to be calling the routine from the other utility! I'll need to go back to my coding and verify I have the CLASS defined correctly, and will also rename this function in my new code.
     
    Thanks Ken and Arthur for your support.
  • Dave,
    I always think example code is good to look at , though I don't claim mine is good code.
    I took one of my PCLs and cut it down as an example (I think it had a similar mechanism to the one you want). This form was designed to always be hidden in normal use but also could be displayed, it is essentially just a databox. The data type can be changed dynamically. I added a callback on the box itself(normally it just has a cb on the frame) just to show all the callback interactions going on(not a normal thing at all). I attach my pcl and a compiled plb.
    To run it, open a db with some 2d elements and then:
    !!lib add ajh_pick_cb.plb
    ajh_pick_cb.init()
    ajh_pick_cb.selany("ELEM2D")
     
    $as you pick elements it will echo like:
    $# sdb_callback : VALUE_CHANGED
    $# sdb_callback : GAIN
    $# sdb_callback : CR
    $# sdb_callback : LOSE
    $# sdb_callback : VALUE_CHANGED
    $# apply callback: 
    $# Elm 18
    $# sdb_callback : GAIN
    $# sdb_callback : LOSE
    $# sdb_callback : GAIN
    $# sdb_callback : LOSE
    $# sdb_callback : VALUE_CHANGED
    $# apply callback: 
    $# Elm 13
     
    the sdb_callbacks are from the databox and
    the apply callback is the frames auto execute callback.
     
    Maybe this is of use for comparison purposes.
    cheers
    Arthur

    Attached Files (1)
  • Thanks, Arthur! I do appreciate the sample code.
     
    Thanks again.​