Guild Companies, Inc.  
 
Midrange Programmer - How-To Advice & Free Code
OS/400 Edition
Volume 1, Number 5 - March 14, 2002

ILE Static Binding

by Kevin Vandever

[The code for this article is available for download.]

ILE has been around for about eight years, yet many iSeries shops still considered it new technology. The primary reason is that the Integrated Language Environment is so different from what we are used to. Things like service programs, subprocedures, activation groups, and static binding are all foreign concepts to our midrange-programming minds. In this article, I am going to discuss the ILE concept of static binding and explain why you might want to use it and when to employ which static binding technique.

What Is Static Binding?

Binding is simply a method of combining two or more iSeries objects into a single program or service program. Binding by itself is not a new concept; all of use have bound programs together since we were little midrange programmers. Whenever you call one program from another using the CALL operation, you are dynamically binding those programs. Dynamic binding means that neither program knows about the other until the call takes place. In that sense it is dynamic, because all the binding is happening right at the time the program is called, and subsequent calls to the same program might be different, depending on what has been changed in the program since the last time it was called. It's hip, it's unattached, but, as you'll see, it comes with a cost. Static binding, on the other hand, is the method of binding two objects together well before they ever use each other. This type of binding is static, in that the objects are bound together and the relationship between those bound objects remains consistent until one of the objects is changed and everything is statically bound again.

Why Do It?

The primary reason for statically binding, as opposed to dynamically binding or not binding at all, is that it removes the performance penalty that comes with breaking code into smaller, more manageable pieces to perform specific tasks. Dynamic binding is expensive because every call to a program must go through program call resolution and program startup tasks. Not binding at all removes this performance hit but causes monolithic programs that are next to impossible to maintain and do not promote code reuse. Static binding allows you to code in a more modular fashion without incurring the performance hit associated with dynamic binding. This is accomplished differently, depending on the type of static binding you employ.

Binding Building Blocks

Now that I have explained static binding and why you should use it, I want to discuss the ILE building blocks in a little more detail. Before ILE, we only concerned ourselves with program objects (*PGM). With the introduction of ILE, there came along some new object types that are the building blocks to static binding. Below is a description of each:

  • Program (*PGM) is still around but is now created using the CRTBNDxxx command (where xxx represents the language, such as RPG, CL, or CBL) and the CRTPGM command, which allows you to statically bind two or more modules together to form a program. *PGMs can be called using the dynamic CALL operation or, if created by binding two or modules, those modules can be called using a bound call (CALLB in RPG) or a prototyped call (CALLP in RPG).
  • Module (*MODULE) is the basic building block of static binding. Modules allow you to organize related tasks into smaller units of code, which can then be bound together into programs or service programs. They cannot be called using the dynamic CALL operation but are, instead, called with either the bound call or the prototyped call. Modules are created using the CRTxxxMOD command (where xxx represents the language used). NOMAIN modules cannot be called directly. Instead, the subprocedures contained inside the module are called using prototyped call (CALLP in RPG).
  • Service Program (*SRVPGM) can be viewed as a collection of subroutines packaged together and accessible to the outside world. Service programs are the ILE packages used for bind by reference, meaning that the exports (subprocedures you exported during the creation of your service program) are loaded into memory and shared with other programs and service programs that need them. You use the CRTSRVPGM command to create a service program.
  • Procedures (also known as subprocedures) are the smallest component of static binding and are self- contained high-level-language statements used to perform a specific task. There is no related object type to describe the subprocedure; it is only used as a building block to create a *MODULE. One or more subprocedures are created inside a module and then compiled into a program or service program.
  • Two Flavors

    There are two types of static binding: Bind by copy and bind by reference. Bind by copy is accomplished by copying two or more modules into a program. In this way, the finished product performs just a like a program with multiple subroutines, except that each module can be called from the other modules within the program. I've included three modules (module1, module2, and callmods) that you can compile together to form a program. In my example, I will create a program, PROGRAM1, that will be comprised of my three modules. The modules are created first, then all the modules are compiled together as a *PGM, using the CRTPGM command. In this way all the modules are copied into the program. The following is the sequence used to create the program:

    CRTRPGMOD MODULE(YourLib/MODULE1) SRCFILE(YourLib/QRPGLESRC)
    CRTRPGMOD MODULE(YourLib/MODULE2) SRCFILE(YourLib/QRPGLESRC)
    CRTRPGMOD MODULE(YourLib/CALLMODS) SRCFILE(YourLib/QRPGLESRC)
    CRTPGM PGM(YourLib/PROGRAM1) MODULE(CALLMODS MODULE1 MODULE2) 
    ENTMOD(CALLMODS)
    

    Now MODULE1 and MODULE2 can be called from within PROGRAM1. If we had bound other modules, by copy, into PROGRAM1, we could have called them, too. Notice that CALLMODS actually calls the other two modules, using the CALLB operation. That's because the CALLMODS module was made the program entry procedure (PEP) by the ENTMOD parameter in the CRTPGM command. That doesn't mean it is the only module from which you can call other modules; it simply means that when your program is called, this module is the one it will start in.

    Bind by reference works a little differently. Modules are still bound together to form an object, but this time the object is a service program (*SRVPGM), not a program. (For more information on service programs, check out my article "The Basics of ILE Service Programs.") The service program is then loaded into the memory of the calling program, at runtime. There exists only one copy of the code, but that copy is loaded at runtime and shared with other programs or service programs that might need it. A service program is like an RPG program with a bunch of subroutines that can be called from the outside world or, in java speak, as a class with multiple methods. A service program cannot be called directly; rather, each component (subprocedure) is called directly. This adds a new spin to RPG, and that spin is multiple entry points. I've included two modules from my service program article (CstOps and CstData), along with their corresponding prototypes (CstOpsPR and CstDataPR). I will use these modules to build my service program. A service program is not all that different from a program, except that each module contains one or more subprocedures and those subprocedures, not the modules, are the entry points into the service program. Another difference is that the modules contained in service programs contain no program entry procedure (PEP), as our program did. This is accomplished by adding an H-spec (NOMAIN) entry in each module. NOMAIN states that there is no PEP, and therefore much of the tasks done at program startup, including the loading of the logic cycle, are not done. This lightens the object significantly. It also means that in addition to the service program not being able to be called directly, the modules can't be called, either. The only way to access the service program is through the subprocedures. The module becomes little more than a container for its subprocedures. (This is discussed further in "The Basics of ILE Service Programs." For more information on subprocedures, check out Ted Holt's article "Subprocedures: Better than Subroutines.")

    These are the steps necessary to build the service program from the given modules:

    CRTRPGMOD MODULE(YourLib/MODULE1) SRCFILE(YourLib/QRPGLESRC)
    CRTRPGMOD MODULE(YourLib/MODULE2) SRCFILE(YourLib/QRPGLESRC)
    CRTSRVPGM SRVPGM(YourLib/SRVPGM1) MODULE(MODULE1 MODULE2) EXPORT(*ALL)
    

    The EXPORT(*ALL) parameter tells which subprocedures you want to make available to the outside world. In my service program article, I included a program you can use to test out the calls to the subprocedures inside your service program. You will also find an explanation of a binding directory, which is a way to organize service programs and modules to make it easier to bind them by reference to other programs and service programs. Please refer to that article for detailed explanation on testing your service program.

    So bind by copy is achieved when everything, caller and callee, are bound together in a program (*PGM). Bind by reference is achieved when one or more subprocedures are combined to create a NOMAIN module and one or more NOMAIN modules are combined to create a service program (*SRVPGM). Let's look closer at the building blocks.

    Vanilla or Chocolate?

    Great. So you can bind by copy or bind by reference. Or you can still dynamically bind with a traditional CALL operation. So when do you do which? Well, there is no hard and fast rule. If your shop was really comfortable with bind by copy and just hated bind by reference, I would not try to force you into bind by reference; however, there are some guidelines that you can follow.

    If a module is going to be called by one program, and one program only, use bind by copy. It is the best overall performer in this case, because the code is copied right into the program at compile time. However, this becomes a potential maintenance and compile nightmare if you decide you are going to use bind by copy and the module is going to be called by many programs.

    If you have code that is going to be called by many different programs, create subprocedures and compile them into modules then further into service programs. You will take a performance hit the first time the subprocedure is called for each job, but subsequent calls will perform as fast as bind by copy. Because of the first-call performance hit, if the code is going to be called infrequently, you may want to choose another binding strategy.

    That other binding strategy is dynamic binding. Yes, it's still supported and still has value. If you have code that is going to be called by multiple programs, but infrequently, this is still the way to go. The advantage here is that you don't load the program unless you actually use it. The performance hit will be high each time you call it, so use this strategy only for multiple, infrequently called programs.

    Time to Take a Nap

    There you have it. I know I've thrown a lot at you, but take the information in this article along with details from the referenced articles and give it a try. It's really not that bad once you get used to it. Besides, you will need to have the basics down in order to move onto the really fun stuff such as activation groups, signatures, and more complex real-world applications.

    Sponsored By
    CLIENT SERVER DEVELOPMENT

    LEARN SQL FROM
    THE SQL EXPERT

    Howard F. Arner, Jr.

    Buy your copy of iSeries and AS/400 SQL at Work direct from the author, Howard F. Arner, Jr. This is THE book to teach you SQL on the iSeries and AS/400 platform.

    Howard takes you from the beginning of the book to the end with information that is useful for beginners and experts alike. The book comes with a CD that has all of the sample data and queries used in the book and a FREE copy of SQLThing that you can use to work through the examples in the book, so you learn by doing.

    With Howard's expert guidance, you'll learn and understand many topics, including the following:

    • Relational Concepts and Terms
    • SQL Select Basics
    • Manipulating Data in SQL Tables
    • Advanced Select Statements
    • Cursors, Transactions, Journals, and Logging
    • Debugging SQL Statements and Enhancing Performance
    • Stored Procedures
    • Embedded SQL in RPG

    Howard F. Arner, Jr., is a programmer who has published extensively on integration of AS/400 legacy systems. In his book, iSeries and AS/400 SQL at Work, Howard provides detailed coverage of SQL for business environments by using practical examples--available on the CD--to be performed by the reader. More advanced chapters teach how to become proficient in industry-standard SQL to manipulate AS/400 data, use scalar functions to summarize data, and make legacy RPG and COBOL programs AS/400-compatible. This is the perfect guide for beginners and advanced SQL users.

    Here's what readers are saying about iSeries and AS/400 SQL at Work by Howard F. Arner:

    Anyone working with AS/400 query should look into buying this book. Now using AS/400 query seems a little odd and very cumbersome. His writing is laid out very well and is easy to read. While reading this, I felt that he was actually there explaining the chapters to me as a one-on-one instructor. -- Jonathan Tripp, Deerfield Beach, Florida

    If you wondered how to call AS/400 programs from your Visual Basic program correctly, this book is your one source for how to do so. It's the first book on the market that answered all of my client/server questions when I deal with PC to AS/400 programming tasks.

    Not only does Howard do a good job of explaining how stored procedures work, but he gives some great coding examples on how to get you up and running correctly. Howard goes the extra mile and talks about performance, too--one thing that normally is lacking in many other books. -- Bob Butcher, Sidney, New York

    Take your knowledge and understanding of SQL to the next level. Order your copy at SQLThing.com.

    THIS ISSUE
    SPONSORED BY:
    mrc
    Client Server Dev.
    COMMON
    Aldon Computer Group
    Profound Logic Software
    Tramenco
    BACK ISSUES
    TABLE OF CONTENTS
    Displaying Static HTML Pages from the iSeries
    ILE Static Binding
    JSP Server-Side Error Handling, Part 2
    Getting Started with Qshell Scripts
    Introduction to Communications Console and CODE/400's Code/Editor
    Call iSeries Programs Using SQL
      Newsletters | Subscribe | Advertise | About Us | Contact | Search | Home  
      Last Updated: 2/13/02
    Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.