ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Calling IBM API's and using ALIGN

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

  • Calling IBM API's and using ALIGN

    Hello.

    When calling IBM API's is it a mistake to include the keyword "ALIGN" on the data structure definitions that are passed to the API?

    My gut feeling is yes, it is a mistake. However I've seen the API's perform fine and return valid data with the keyword specified.

    Thanks in advance,

    Mike

  • #2
    Basically you only need to use align on an API if told to do so. As to it working with align specified - well it will in most cases since there would have been nothing that needed alignment in the first place. Align is a no-op if there is no alignment needed.

    As the docs say, "The ALIGN keyword is used to align float, integer, and unsigned subfields.​" - Note "subfields". Most APIs don't use structures like that. Also one of the primary reasons for adding align(*full) to the compiler was to deal with DS arrays - again something not often used by APIs.

    Comment


    • #3
      Thanks for your response, JonBoy.

      Most IBM API's have 4-byte binary fields (10-byte integer) in one or more data structures that the API requires, so I don't agree with your first statement.

      Alignment is typically done when prototyping C functions, to match the C structure. But the IBM API's that I'm referring to aren't C functions, they're the "Q" API's.

      So I'm still not sure why the call succeeds when using ALIGN with the IBM API's.

      Comment


      • #4
        The call may be succeeding because the integer subfields are correctly aligned in the API structures. I don't know whether that would happen by design or not.

        I see the _Packed keyword in many members of QSYSINC/H Q*. If the C struct is defined with _Packed, the RPG data structure should not have ALIGN.

        If the C struct does not have _Packed, the RPG data structure should have ALIGN(*FULL).

        Comment


        • #5
          There are actually two reasons for ALIGN(*FULL):
          • For non-arrays, ALIGN(*FULL) makes the aligned data structure as big as C would define it: A multiple of the biggest alignment requirement for the subfields. For example, if the structure has a 4-byte integer followed by a 1 byte charaacter, the integer requires 4 byte alignment, so the size is 8, a multiple of 4, instead of the RPG's default ALIGN size of 5.
          • For arrays, even with simple ALIGN, RPG does define the array big enough for the alignment, but %SIZE(elem) only returns the size actually needed for the subfields, shorter than actual size of the elements. With ALIGN(*FULL), %SIZE returns the true size of each element, which makes it easier to call functions like bsearch() and qsort().
          The first scenario happens for the data structure used by the regex APIs. That's where we first became aware of the problem. If only the simple ALIGN keyword is used, the data structure is too short, and data corruption can happen if the regex API changes the entire parameter - if I recall correctly, it's the regcomp() API. With ALIGN(*FULL), the RPG data structure matches the data structure used by the API.​ (The RPG data structure can also be corrected by using the LEN keyword on the RPG data structure, or by adding an extra dummy subfield at the end.)

          Comment

          Working...
          X