i5_ToolKit Passing Structures part II

[adrotate group=”7″]
While playing around with the passing of structures into our Service Program via the i5_toolkit functions we came across the need to pass in more than one structure to the service program.

Having spent sometime playing with how to correctly pass in variables we thought passing in a number of structures should be easy, unfortunately we stumbled across a problem. We have a service program which reads the messages from a data queue using the QMHRDQM API which have a number of messages in related to the DR4i requests for receiver changes. The message consists of a number of fields some of which are the same for every message (the journal information) and others which are different every time (the receiver names and library).

We could have simply copied the data from each message back and just ignored the fact that the journal information would be the same every time. Its only 30 bytes so even for 100 messages its a small amount of data. But as we always do, we want to make this as slick as possible so we only want to return the information which does not change once. Our first attempts at building the structure failed and resulted in the IBM i program ending mysteriously with no output as to why (Its a known bug which is now fixed in the latest extension we were shipped). So we sent of a message to EasyCom asking what we were doing wrong and asked for their support.

In the meantime, (they are 6 hours ahead of us so they would have not seen the message until the next day) we decided to change the service program slightly and pass in three additional character strings for the journal information. This is the resulting array setup for the program prepare.

$desc = array(
      array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
      array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array(
            array("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
            array("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))));

This is what the service program was set up to use.

int get_dq_ents(int *num, char *DQ, char *Jrn, char *JrnLib, char *JrniASP, DQ_Ent_t ents[])

This worked perfectly but we wanted to find out how to pass in the multiple structures. EasyCom came back with the reply and the following code.

$desc = array (
      array ("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT ),
      array ("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10" ),
      array ("DsName" => "jrninf", "count" => 1, "DSParm" => array (
      array ("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
      array ("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
      array ("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ) ) ),
      array ("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array (
      array ("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
      array ("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ) ) ) );

The problem was we were using CountRef for each structure as shown below.

$desc = array(
array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
array("DsName" => "jrninf", "CountRef" => 1, "DSParm" => array (
      array("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))),
array("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array(
      array("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
      array("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))));

EasyCom support explained that we should not use the CountRef variable more than once and that Count should be used for the first structure quantity (probably would work for all but CountRef was appropriate for the setting of the second array of structures?). The service program was updated to accept the additional structure and the process now works flawlessly!

We had tried a number of the examples from the manuals all of which failed for various reasons, so if you are like us struggling to get the structure and array technology clear in you mind maybe this will help?

Chris…

2 thoughts on “i5_ToolKit Passing Structures part II”

  1. We may have got the information wrong reference the use of the CountRef parameter and are discussing the problem with EasyCom. You should be able to use the CountRef parameter multiple times, something we tried and saw issues with? They have also explained you can pass in no Count/CountRef parameter which did not seem to work for us either? As soon as we get clarification we will post the results. Keep watching!

  2. Clarification!

    When you are passing in the DSParms parameters you can use “Count” to determine how many structures there are and this can reference a PHP variable such as $num which is set within your script. When you use “CountRef” you must pass in the string of the parameter which is part of the description you are passing in to the program prepare. Basically you are saying look at one of the other variables that is contained in the parameter array I am using to prepare the program call. The following code sent by EasyCom cleared it up for me..

    When you write :
    array(“DSName” => “jrninfo”, “CountRef” => ‘numjrn’, “DSParm” => array(

    ‘numjrn’ represents a name inside the description, not a php variable.

    So you also can write:
    array(“name” => “numents”, “io” => I5_IN, “type” => I5_TYPE_INT),
    array(“name” => “numjrn”, “io” => I5_IN, “type” => I5_TYPE_INT),
    array(“name” => “dtaq”, “io” => I5_IN, “type” => I5_TYPE_CHAR, “length” => “10”),
    array(“DSName” => “jrninfo”, “CountRef” => ‘numjrn’, “DSParm” => array(
    (and put 1 to the numjrn parameter in the call).

    I think this makes it all a lot clearer??

    Chris…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.