The EXTPROC keyword can have one of the following formats:
Use *CNOWIDEN or *CWIDEN if your program uses return values or parameters passed by value with data types that C handles differently from RPG. Use *CWIDEN or *CNOWIDEN when defining an RPG procedure that is to be called by C, or when defining the prototype for a C procedure, where the returned value or a parameter passed by value is 1A, 1G or 1C, 5U, 5I, or 4F.
Use *CNOWIDEN if the ILE C source contains #pragma argument(procedure-name,nowiden) for the procedure; otherwise, use *CWIDEN.
For more information about invoking Java procedures, see IBM Rational Development Studio for i: ILE RPG Programmer's Guide.
The EXTPROC keyword indicates the external name of the procedure whose prototype is being defined. The name can be a character constant or a procedure pointer. When EXTPROC is specified, a bound call will be done.
If neither EXTPGM or EXTPROC is specified, then the compiler assumes that you are defining a procedure, and assigns it the external name found in positions 7-21.
If the name specified for EXTPROC (or the prototype or procedure name, if neither EXTPGM or EXTPROC is specified) starts with "CEE" or an underscore ('_'), the compiler will treat this as a system built-in. To avoid confusion with system provided APIs, you should not name your procedures starting with "CEE".
For example, to define the prototype for the procedure SQLAllocEnv, that is in the service program QSQCLI, the following definition specification could be coded:
D SQLEnv PR EXTPROC('SQLAllocEnv')
If a procedure pointer is specified, it must be assigned a valid address before it is used in a call. It should point to a procedure whose return value and parameters are consistent with the prototype definition.
When a prototype is specified for a procedure, the EXTPROC keyword is specified for the prototype. Otherwise, the EXTPROC keyword is specified for the procedure interface. It is only necessary to explicitly specify a prototype when the procedure will be called from another RPG module. When the procedure is only called from within the same module, or when it is only called by non-RPG callers, the prototype can be implicitly derived from the procedure interface.
Figure 122 shows an example of the EXTPROC keyword with a procedure pointer as its parameter.
* Assume you are calling a procedure that has a procedure
* pointer as the EXTPROC. Here is how the prototype would
* be defined:
D DspMsg PR 10A EXTPROC(DspMsgPPtr)
D Msg 32767A
D Length 4B 0 VALUE
* Here is how you would define the prototype for a procedure
* that DspMsgPPtr could be assigned to.
D MyDspMsg PR LIKE(DspMsg)
D Msg 32767A
D Length 4B 0 VALUE
* Before calling DSPMSG, you would assign DSPMSGPPTR
* to the actual procedure name of MyDspMsg, that is
* MYDSPMSG.
C EVAL DspMsgPPtr = %paddr('MYDSPMSG')
C EVAL Reply = DspMsg(Msg, %size(Msg))
...
P MyDspMsg B
char RPG_PROC (short s, float f);
char C_PROC (short s, float f);
#pragma argument(RPG_PROC, nowiden)
#pragma argument(C_PROC, nowiden)
/* "fn" calls the RPG procedure with unwidened parameters, */
/* and expects the return value to be passed according to C */
/* conventions. */
void fn(void)
{
char c;
c = RPG_PROC(5, 15.3);
}
/* Function C_PROC expects its parameters to be passed unwidened.*/
/* It will return its return value using C conventions. */
char C_PROC (short s, float f);
{
char c = 'x';
if (s == 5 || f < 0)
{
return 'S';
}
else
{
return 'F';
}
}
D RPG_PROC PR 1A EXTPROC(*CNOWIDEN : 'RPG_PROC')
D short 5I 0 VALUE
D float 4F VALUE
D C_RPOC PR 1A EXTPROC(*CNOWIDEN : 'C_PROC')
D short 5I 0 VALUE
D float 4F VALUE
P RPG_PROC B EXPORT
D PI 1A
D short 5I 0 VALUE
D float 4F VALUE
D char S 1A
* Call the C procedure
C EVAL c = C_PROC(4 : 14.7)
* Return the value depending on the values of the parameters
C IF short < float
C RETURN 'L'
C ELSE
C RETURN 'G'
C ENDIF
P E
char RPG_PROC (short s, float f);
char C_PROC (short s, float f);
/* Function "fn" calls the RPG procedure with widened parameters,*/
/* and expects the return value to be passed according to C */
/* conventions. */
void fn(void)
{
char c;
c = RPG_PROC(5, 15.3);
}
/* Function C_PROC expects its parameters to be passed widened. */
/* It will return its return value using C conventions. */
char C_PROC (short s, float f);
{
char c = 'x';
if (s == 5 || f < 0)
{
return 'S';
}
else
{
return 'F';
}
}
D RPG_PROC PR 1A EXTPROC(*CWIDEN : 'RPG_PROC')
D short 5I 0 VALUE
D float 4F VALUE
D C_PROC PR 1A EXTPROC(*CWIDEN : 'C_PROC')
D short 5I 0 VALUE
D float 4F VALUE
P RPG_PROC B EXPORT
D PI 1A
D short 5I 0 VALUE
D float 4F VALUE
D char S 1A
* Call the C procedure
C EVAL c = C_PROC(4 : 14.7)
* Return the value depending on the values of the parameters
C IF short < float
C RETURN 'L'
C ELSE
C RETURN 'G'
C ENDIF
P E
/* CL procedure CL_PROC */
DCL &CHAR1 TYPE(*CHAR) LEN(1)
/* Call the RPG procedure */
CALLPRC RPG_PROC RTNVAR(&CHAR1)
D RPG_PROC PR 1A EXTPROC(*CL : 'RPG_PROC')
P RPG_PROC B EXPORT
D PI 1A
C RETURN 'X'
P E
P isValidCust B EXPORT
D PI N EXTPROC(*CL : 'isValidCust')
D custId 10A CONST
D isValid S N INZ(*OFF)
/free
... calculations using the "custId" parameter
return isValid;
/end-free
P E