RPGLE Prototypes - defining the Procedures

What is a prototype?

In RPGLE, particularly in free-format style, a prototype serves as a function signature, outlining the exact way a program or procedure should be invoked. It's essentially the "agreement" that details the routine's name, input parameters, and output type, all without providing the underlying code.

In IBM i RPGLE, a prototype is basically the diva's dressing room memo for your code: it spells out exactly how a procedure or program expects to be summoned, down to the name, parameters, and what it spits back, without spilling a drop of the actual implementation.

Think of it as the "please don't call me unless you're wearing this" contract that keeps your modular code from turning into a chaotic family reunion. Declare one with DCL-PR, toss in your params like picky guest lists, and wrap with END-PR. Call it wrong? The compiler rolls its eyes and halts the compile, saving you from debugging disasters that could make even the most stoic sysadmin chuckle nervously.

Purpose and Benefits

Type safety: Ensures parameters passed match expected types.

Modularity: Lets you call procedures across modules or service programs.

Reusability: You can /COPY prototypes into multiple programs.

Clarity: Makes your code easier to read and maintain.

RPGLE Prototype Syntax (Free-form)

dcl-pr MyProcedure int(10);
  parm1 char(10) const;
  parm2 packed(7:2);
end-pr;
  • dcl-pr starts the prototype block.
  • MyProcedure is the name of the procedure.
  • int(10) is the return type (optional if void).
  • Each parameter is defined with its type and optional keywords like const, options(*nopass), etc.
  • end-pr closes the prototype.

Calling External Programs

If you're calling an external program (like QCMDEXC), you use extpgm to process the call in the same way as an internal procedure

This prototype defines the call to QCMDEXC and you could use it like this:

// Prototype for QCMDEXC API
dcl-pr RunCommand extpgm('QCMDEXC');
  command char(3000) const;
  length packed(15:5) const;
end-pr;

dcl-s cmdString char(3000);
dcl-s cmdLen packed(15:5);

// Build the command string
cmdString = 'DSPJOB OUTPUT(*PRINT)';

// Calculate the length (trim trailing blanks)
cmdLen = %len(%trimr(cmdString));

// Call the API
RunCommand(cmdString:cmdLen);

dsply ('Command executed! Check your printer spool.');

*inlr = *on;

Looking for a more obvious business example?

How about a simple procedure prototype for a "CalculateTax" function:

// Prototype for the procedure
dcl-pr CalculateTax extproc('CALCTAX');
  Amount packed(9:2);
  Rate packed(3:2);
  TaxResult char(10);
end-pr;

Here, the prototype defines a procedure expecting an amount and rate, returning a tax result string. When calling it (e.g., CalculateTax(100.00 : 0.08 : result);), the compiler checks against this definition.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>