From: <wda...@us...> - 2008-07-24 19:31:49
|
Revision: 2778 http://oorexx.svn.sourceforge.net/oorexx/?rev=2778&view=rev Author: wdashley Date: 2008-07-24 19:31:58 +0000 (Thu, 24 Jul 2008) Log Message: ----------- ArtifactID: None Comment: Initial changes to the PG for 4.0. Lots more later. Modified Paths: -------------- docs/trunk/rexxpg/api.sgml docs/trunk/rexxpg/command.sgml docs/trunk/rexxpg/rexxpg.sgml Added Paths: ----------- docs/trunk/rexxpg/classicapi.sgml Modified: docs/trunk/rexxpg/api.sgml =================================================================== --- docs/trunk/rexxpg/api.sgml 2008-07-24 18:56:16 UTC (rev 2777) +++ docs/trunk/rexxpg/api.sgml 2008-07-24 19:31:58 UTC (rev 2778) @@ -41,21 +41,20 @@ # ######################################################################### --> -<appendix id="os2api"><title>Rexx Application Programming Interfaces</title> +<appendix id="api4x"> +<title>Rexx C++ Application Programming Interfaces</title> <para>This appendix describes how to interface applications to Rexx or extend -the Rexx language by using Rexx application programming interfaces (APIs). +the Rexx language by using Rexx C++ application programming interfaces (APIs). As used here, the term application refers to programs -written in languages other than Rexx. This is usually the C language. Conventions -in this appendix are based on the C language. Refer to a C programming reference -manual if you need a better understanding of these conventions.</para> -<para>The features described here let an application extend many parts of the +written in C++. +</para> +<para>The features described here let a C++ application extend many parts of the Rexx language or extend an application with Rexx. This includes creating handlers -for subcommands, external functions, and system exits. </para> +for Rexx methods, external functions, and system exits. </para> <variablelist> -<varlistentry><term>Subcommands</term> -<listitem><para>are commands issued from a Rexx program. A Rexx expression is evaluated -and the result is passed as a command to the currently addressed subcommand -handler. Subcommands are used in Rexx programs running as application macros. +<varlistentry><term>Rexx methods</term> +<listitem><para>are extensions to ooRexx classes. An ooRexx class can define a +method as being contained in an external shared library. </para></listitem></varlistentry> <varlistentry><term>Functions</term> <listitem><para>are direct extensions of the Rexx language. An application can create @@ -68,4369 +67,37 @@ replacing Rexx system requests. </para></listitem></varlistentry> </variablelist> -<para>Subcommand, function, and system exit handlers have similar coding, compilation, -and packaging characteristics.</para> -<para>In addition, applications can manipulate the variables in Rexx programs -(see <link linkend="os2vpi">Variable Pool Interface</link>), -and execute Rexx routines directly from memory -(see <link linkend="macrosp">Macrospace Interface</link>).</para> +<para>Methods, functions, and system exit handlers have similar coding, +compilation, and packaging characteristics. +</para> +<para>In addition, applications can call methods defined on an ooRexx class and +execute them from externally defined methods and functions.</para> -<section id="apigenc"><title>Handler Characteristics</title> -<para>The basic requirements for subcommand, function, and system exit handlers -are: </para> -<itemizedlist> -<listitem><para>Rexx handlers must use the APIENTRY (_stdcall) linkage convention. -Handler functions should be declared with the appropriate type definition -from the Rexx.H include file. Using <computeroutput>C++</computeroutput>, -the functions must be declared as <computeroutput>extern C</computeroutput>: -<itemizedlist> -<listitem><para>RexxSubcomHandler</para></listitem> -<listitem><para>RexxFunctionHandler</para></listitem> -<listitem><para>RexxExitHandler</para></listitem></itemizedlist></para></listitem> -<listitem><para>A Rexx handler must be packaged as either of the following: -<itemizedlist> -<listitem><para>An exported routine within a dynamic-link library (DLL) -</para></listitem> -<listitem><para>An entry point within an executable (EXE) module -</para></listitem> -</itemizedlist> -</para></listitem> -<listitem><para>A handler must be registered with Rexx before it can be used. Rexx uses -the registration information to locate and call the handler. For example, -external function registration of a dynamic-link library -external function identifies both the dynamic-link library -and routine that contains the external function. Also note: -<itemizedlist> -<listitem><para>Dynamic-link library handlers are global to the system; any -Rexx program can call them.</para></listitem> -<listitem><para>Executable file handlers are local to the registering process; -only a Rexx program running in the same process as an executable module can call -a handler packaged within that executable module.</para></listitem> -</itemizedlist></para></listitem></itemizedlist> +<section id="intertreterapi"><title>Rexx Interpreter API</title> +<para>This section describes how to invoke the Rexx interpreter via the +RexxCreatInterpreter API.</para> </section> -<section id="rxstrings"><title>RXSTRINGs</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>RXSTRING data structure</secondary></indexterm> -<indexterm><primary>application programming interfaces</primary> -<secondary>RXSTRING data structure</secondary> -<tertiary>RXSTRING</tertiary></indexterm> -<indexterm><primary>RXSTRING</primary></indexterm> -<indexterm><primary>RXSTRING</primary> -<secondary>definition</secondary></indexterm> -<para>Many of the Rexx application programming interfaces pass Rexx character -strings to and from a Rexx procedure. The RXSTRING data structure is used -to describe Rexx character strings. An RXSTRING is a content-insensitive, -flat model character string with -a theoretical maximum length of 4 gigabytes. The following structure defines -an RXSTRING:</para> -<programlisting> -<![CDATA[ -typedef struct { - ULONG strlength; /* length of string */ - PCH strptr; /* pointer to string */ -} RXSTRING; - -typedef RXSTRING *PRXSTRING; /* pointer to an RXSTRING */ -]]> -</programlisting> - -<para>Notes:</para> -<orderedlist> -<listitem><para>The Rexx.H include file contains a number of convenient macros -for setting and testing RXSTRING values.</para></listitem> -<listitem><para> -An RXSTRING can have a value (including the null string, -"") or it can be empty. -<itemizedlist> -<listitem><para>If an RXSTRING has a value, the -<emphasis role="italic">strptr</emphasis> field is not null. The -RXSTRING macro RXVALIDSTRING(string) returns TRUE.</para></listitem> -<listitem><para>If an RXSTRING is the Rexx null string (""), the -<emphasis role="italic">strptr</emphasis> field -is not null and the <emphasis role="italic">strlength</emphasis> field is 0. -The RXSTRING macro RXZEROLENSTRING(string) returns TRUE.</para></listitem> -<listitem><para>If an RXSTRING is empty, the field -<emphasis role="italic">strptr</emphasis> is null. The RXSTRING -macro RXNULLSTRING(string) returns TRUE.</para></listitem> -</itemizedlist> -</para></listitem> -<listitem><para>When the Rexx -interpreter passes an RXSTRING to a subcommand handler, external function, -or exit handler, the interpreter adds a -<indexterm><primary>RXSTRING</primary> -<secondary>null terminated</secondary></indexterm> -null character (hexadecimal zero) -at the end of the RXSTRING data. You can use the C string library functions -on these strings. However, the RXSTRING data can also contain null characters. -There is no guarantee that the first null character encountered in an RXSTRING -marks the end of the string. You use the C string functions only when you -do not expect null characters in the RXSTRINGs, such as file names passed -to external functions. The <emphasis role="italic">strlength</emphasis> field -in the RXSTRING does not include the terminating null character.</para></listitem> -<listitem><para>On calls to subcommand -<indexterm><primary>RXSTRING</primary> -<secondary>returning</secondary></indexterm> -and external functions handlers, as well as to some of the exit handlers, -the Rexx interpreter expects that an RXSTRING value is returned. The Rexx -interpreter provides a default RXSTRING with a -<emphasis role="italic">strlength</emphasis> of 256 for -the returned information. If the returned data is shorter than 256 characters, -the handler can copy the data into the default RXSTRING and set the -<emphasis role="italic">strlength</emphasis> field to the length returned.</para> -<para>If the returned data is longer than 256 characters, -a new RXSTRING can be allocated using -<computeroutput>GlobalAlloc(size)</computeroutput>. The -<emphasis role="italic">strptr</emphasis> field must point to the new storage -and the <emphasis role="italic">strlength</emphasis> must -be set to the string length. The Rexx interpreter returns the newly allocated -storage to the system for the handler routine.</para></listitem> -</orderedlist> +<section id="apiconcepts"><title>Introduction to API Vectors</title> +<para>This section provides a general description of API vectors and how to use +them.</para> </section> -<section id="rxinvk"><title>Calling the Rexx Interpreter</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>invoking the Rexx interpreter</secondary></indexterm> -<indexterm><primary>calling the Rexx interpreter</primary></indexterm> -<indexterm><primary>invoking the Rexx interpreter</primary></indexterm> -<indexterm><primary>Rexx interpreter, invoking</primary></indexterm> -<para>A Rexx program can be run directly from the command prompt -of the operating system, or from within an application.</para> - -<section id="invcom"><title>From the Operating System</title> -<para>You can run a Rexx program directly from the operating system -command prompt using Rexx followed by the program name. -See <link linkend="looks">Running a Rexx Program</link>.</para> +<section id="instanceapi"><title>Rexx Instance Interface</title> +<para>This section describes the Rexx instance interface and the methods it +provides.</para> </section> -<section id="fwaa"><title>From within an Application</title> -<para>The Rexx interpreter is a dynamic-link library -(DLL) routine (or Unix/Linux shared object). Any application -can call the Rexx interpreter to run a Rexx program. The interpreter is fully -reentrant and supports Rexx procedures running on several threads within the -same process.</para> -<para>A C-language prototype for calling Rexx is in the Rexx.H include file.</para> +<section id="threadapi"><title>Rexx Thread Interface</title> +<para>This section describes the Rexx thread interface and the methods it +provides.</para> </section> -<section id="rexxstartfu"><title>The RexxStart Function</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>invoking the Rexx interpreter</secondary> -<tertiary>RexxStart</tertiary></indexterm> -<indexterm><primary>RexxStart</primary></indexterm> -<para>RexxStart calls the Rexx interpreter to run a Rexx procedure. </para> -<programlisting> -retc = RexxStart(ArgCount, ArgList, ProgramName, Instore, EnvName, - CallType, Exits, ReturnCode, Result); -</programlisting> - -<section id="rexxstartparm"><title>Parameters</title> -<para></para> -<variablelist> -<varlistentry><term>ArgCount (LONG) - input</term> -<listitem><para>is the number of elements in the -<emphasis role="italic">ArgList</emphasis> array. This is the -value that the <emphasis role="italic">ARG()</emphasis> built-in function in -the Rexx program returns. <emphasis role="italic">ArgCount</emphasis> -includes RXSTRINGs that represent omitted arguments. Omitted -arguments are empty RXSTRINGs (<emphasis role="italic">strptr</emphasis> -is null).</para></listitem></varlistentry> -<varlistentry><term>ArgList (PRXSTRING) - input</term> -<listitem><para>is an array of RXSTRING structures that are the Rexx program arguments. -</para></listitem></varlistentry> -<varlistentry><term>ProgramName (PSZ) - input</term> -<listitem><para>is the address of the ASCII name of the Rexx procedure. If -<emphasis role="italic">Instore</emphasis> is null, -<emphasis role="italic">ProgramName</emphasis> must contain at least the file name of -the Rexx procedure. You can also provide an extension, drive, and path. -If you do not specify a file extension, the -default is .CMD. A Rexx program can use any extension. If you do not -provide the path and the drive, the Rexx interpreter uses the usual file search -(current directory, then environment path).</para> -<para>If <emphasis role="italic">Instore</emphasis> is not null, -<emphasis role="italic">ProgramName</emphasis> is the name used in the -PARSE SOURCE instruction. If <emphasis role="italic">Instore</emphasis> -requests a Rexx procedure from the macrospace, -<indexterm><primary>RexxStart</primary> -<secondary>using macrospace programs</secondary></indexterm> -<emphasis role="italic">ProgramName</emphasis> is the macrospace -function name (see <link linkend="macrosp">Macrospace Interface</link>).</para> -</listitem></varlistentry> -<varlistentry><term>Instore (PRXSTRING) - input</term> -<listitem><para>is -an array of two RXSTRING descriptors for in-storage Rexx procedures. If the -<emphasis role="italic">strptr</emphasis> fields of both RXSTRINGs are null, -the interpreter searches for Rexx procedure -<emphasis role="italic">ProgramName</emphasis> in the Rexx macrospace (see -<link linkend="macrosp">Macrospace Interface</link>). -If the procedure is not in the macrospace, the call to RexxStart terminates -with an error return code. </para> -<para>If either <emphasis role="italic">Instore strptr</emphasis> field -is not null, <emphasis role="italic">Instore</emphasis> is used to run a Rexx -procedure directly from storage.</para> -<variablelist> -<varlistentry><term>Instore[0] -<indexterm><primary>RexxStart</primary> -<secondary>using in-storage programs</secondary></indexterm> -</term> -<listitem><para>is an RXSTRING describing a memory buffer that contains the Rexx procedure -source. The source must be an exact image of a Rexx procedure disk file, complete -with carriage returns, line feeds, and end-of-file characters. -</para></listitem></varlistentry> -<varlistentry><term>Instore[1]</term> -<listitem><para>is an RXSTRING containing the translated image of the Rexx procedure. -If <emphasis role="italic">Instore[1]</emphasis> is empty, the Rexx interpreter returns the -translated image in <emphasis role="italic">Instore[1]</emphasis> when the Rexx procedure -finishes running. The translated image may be used in -<emphasis role="italic">Instore[1]</emphasis> on subsequent RexxStart calls.</para> -<para>If <emphasis role="italic">Instore[1]</emphasis> is -not empty, the interpreter runs the translated image directly. The program -source provided in <emphasis role="italic">Instore[0]</emphasis> is used only if the Rexx -procedure uses the SOURCELINE built-in function. -<emphasis role="italic">Instore[0]</emphasis> can be empty if SOURCELINE -is not used. If <emphasis role="italic">Instore[0]</emphasis> is empty -and the procedure uses the SOURCELINE built-in function, SOURCELINE() -returns no lines and any attempt to access the source returns Error 40.</para> -<para>If <emphasis role="italic">Instore[1]</emphasis> is not empty, -but does not contain a valid Rexx translated image, unpredictable results -can occur. The Rexx interpreter might be able to determine that the translated -image is incorrect and translate the source again.</para> -<para><emphasis role="italic">Instore[1]</emphasis> is both an input and -an output parameter.</para> -</listitem></varlistentry> -</variablelist> -<para>If the procedure is executed from disk, the -<emphasis role="italic">Instore pointer</emphasis> must be null. -If the first argument string in <emphasis role="italic">Arglist</emphasis> -contains the string //T and the <emphasis role="italic">CallType</emphasis> -is RXCOMMAND, the interpreter performs a syntax check on the procedure source, -but does not execute it and does not store any images.</para> -<para>The program calling -RexxStart must release <emphasis role="italic">Instore[1]</emphasis> -using <computeroutput>RexxFreeMemory(ptr)</computeroutput> -when the translated image is no longer needed.</para> -<para>Only the interpreter version that created the image can run the translated -image. Therefore, neither change the format of the translated image of a Rexx -program, nor move a translated image to other systems or save it for later -use. You can, however, use the translated image several times during a single -application execution.</para> -</listitem></varlistentry> -<varlistentry><term>EnvName (PSZ) - input</term> -<listitem><para>is the address of the initial ADDRESS environment name. The ADDRESS -environment is a subcommand handler registered using RexxRegisterSubcomExe -or RexxRegisterSubcomDll. <emphasis role="italic">EnvName</emphasis> is used -as the initial setting for the Rexx ADDRESS instruction. </para> -<para>If <emphasis role="italic">EnvName</emphasis> is null, the file -extension is used as the initial ADDRESS environment. The environment name -cannot be longer than 250 characters.</para> -</listitem></varlistentry> -<varlistentry><term>CallType (LONG) - input</term> -<listitem><para>is the type of the Rexx procedure execution. Allowed execution types -are: -<variablelist> -<varlistentry><term>RXCOMMAND</term> -<listitem><para>The Rexx procedure is a system or application command. Rexx commands -usually have a single argument string. The Rexx PARSE SOURCE instruction -returns <computeroutput>COMMAND</computeroutput> as the second token. -</para></listitem></varlistentry> -<varlistentry><term>RXSUBROUTINE</term> -<listitem><para>The Rexx procedure is a subroutine of another program. The subroutine -can have several arguments and does not need to return a result. The Rexx -PARSE SOURCE instruction returns SUBROUTINE as the second token. -</para></listitem></varlistentry> -<varlistentry><term>RXFUNCTION</term> -<listitem><para>The Rexx procedure is a function called from another program. The subroutine -can have several arguments and must return a result. The Rexx PARSE SOURCE -instruction returns <computeroutput>FUNCTION</computeroutput> as the second -token.</para></listitem></varlistentry> -</variablelist> -</para></listitem></varlistentry> -<varlistentry><term>Exits (PRXSYSEXIT) - input -<indexterm><primary>RexxStart</primary> -<secondary>using exits</secondary></indexterm> -</term> -<listitem><para>is an array of RXSYSEXIT structures defining exits for the Rexx interpreter -to be used. The RXSYSEXIT structures have the following form:</para> -<indexterm><primary>application programming interfaces</primary> -<secondary>RXSTRING data structure</secondary> -<tertiary>RXSYSEXIT</tertiary></indexterm> -<indexterm><primary>application programming interfaces</primary> -<secondary>RXSYSEXIT data structure</secondary></indexterm> -<indexterm><primary>RXSYSEXIT data structure</primary></indexterm> -<programlisting> -<![CDATA[ -typedef struct { - PSZ sysexit_name; /* name of exit handler */ - LONG sysexit_code; /* system exit function code */ -} RXSYSEXIT; -]]> -</programlisting> -<para>The <emphasis role="italic">sysexit_name</emphasis> is the address of an -ASCII exit handler name registered with RexxRegisterExitExe or -RexxRegisterExitDll. <emphasis role="italic">Sysexit_code</emphasis> -is a code identifying the handler exit type. See -<link linkend="sysex">System Exit Interface</link> for exit code -definitions. An RXENDLST entry identifies the system-exit list end. -<emphasis role="italic">Exits</emphasis> must be null if exits are not used.</para> -</listitem></varlistentry> -<varlistentry><term>ReturnCode (PSHORT) - output</term> -<listitem><para>is the integer form of the -<emphasis role="italic">Result</emphasis> string. If the -<emphasis role="italic">Result</emphasis> string is a whole number in the range --(2**15) to 2**15-1, it is converted to an integer and also returned in -<emphasis role="italic">ReturnCode</emphasis>. -</para></listitem></varlistentry> -<varlistentry><term>Result (PRXSTRING) - output</term> -<listitem><para>is the string returned from the Rexx procedure with the Rexx -RETURN or EXIT instruction. A default RXSTRING can be provided for the returned -result. If a default RXSTRING is not provided or the default is too small -for the returned result, the Rexx interpreter allocates an RXSTRING using -<computeroutput>GlobalAlloc(size)</computeroutput>. The caller of RexxStart -is responsible for releasing the RXSTRING storage with -<computeroutput>RexxFreeMemory(ptr)</computeroutput>.</para> -<para>The Rexx interpreter -does not add a terminating null to <emphasis role="italic">Result</emphasis>.</para> -</listitem></varlistentry> -</variablelist> +<section id="buildinglibs"><title>Building an External Library</title> +<para>This section describes how to build an external library.</para> </section> -<section id="rexxstartrc"><title>Return Codes</title> -<para>The possible RexxStart return codes are: </para> -<variablelist> -<varlistentry><term>negative</term> - -<listitem><para>Interpreter errors. See the Appendix in the -<citetitle>Open Object Rexx: Reference</citetitle> for the list of Rexx errors. -</para></listitem></varlistentry> -<varlistentry><term>0</term> -<listitem><para>No errors occurred. The Rexx procedure ran normally. -</para></listitem></varlistentry> -<varlistentry><term>positive</term> -<listitem><para>A system return code that indicates problems finding or loading -the interpreter. See the return codes for the Windows functions -LoadLibrary and GetProcAddress for details. -</para></listitem></varlistentry> -</variablelist> -<para>When a macrospace Rexx procedure (see -<link linkend="macrosp">Macrospace Interface</link>) is not loaded -in the macrospace, the return code is -3 ("Program is unreadable").</para> +<section id="exitsapi"><title>Rexx Exits Interface</title> +<para>This section describes how to define a Rexx exit.</para> </section> - -<section id="rexxstartxmp"><title>Example</title> -<indexterm><primary>RexxStart</primary> -<secondary>example using</secondary></indexterm> -<para></para> -<programlisting> -<![CDATA[ -LONG return_code; /* interpreter return code */ -RXSTRING argv[1]; /* program argument string */ -RXSTRING retstr; /* program return value */ -SHORT rc; /* converted return code */ -CHAR return_buffer[250]; /* returned buffer */ - - /* build the argument string */ - MAKERXSTRING(argv[0], macro_argument, - strlen(macro_argument)); - /* set up default return */ - MAKERXSTRING(retstr, return_buffer, sizeof(return_buffer)); - - return_code = RexxStart(1, /* one argument */ - argv, /* argument array */ - "CHANGE.ED", /* Rexx procedure name */ - NULL, /* use disk version */ - "Editor", /* default address name */ - RXCOMMAND, /* calling as a subcommand */ - NULL, /* no exits used */ - &rc, /* converted return code */ - &retstr); /* returned result */ - - /* process return value */ -... - RexxWaitForTermination(); - /* need to return storage? */ - if (RXSTRPTR(retval) != return_buffer) - GlobalFree(RXSTRPTR(retval)); /* release the RXSTRING */ -]]> -</programlisting> -<para>When RexxStart is executed within an external program (usually -a C program), it runs synchronously with the main Rexx activity (thread) that -it started. That is, when the main activity terminates, RexxStart returns, -and the external program continues running.</para> -<para>To run RexxStart asynchronously, you can start several concurrent -activities from the main activity using START or REPLY (see -<link linkend="concur">Concurrency</link>). -RexxStart is still synchronous to the main activity, that is, it returns when -the main activity terminates, but it is asynchronous to the concurrent activities. -If a concurrent activity runs longer than the main activity, RexxStart returns -when the main activity ends, but the concurrent activity continues to run.</para> -<para>If, however, a concurrent activity is still running when the external program -ends, the activity is terminated. To ensure that all activities finish executing, -use RexxWaitForTermination or a looped RexxDidRexxTerminate in your external -program after RexxStart. The use of RexxWaitForTermination is recommended -also for programs that are not expected to use concurrency.</para> -<para>The following example demonstrates how to call MyCMD.CMD from a Cobol program -(Rexx is running in the same process as the Cobol program).</para> -<programlisting> - PROCESS PGMNAME(MIXED) - * You need to specify Rexx.LIB when you link this program, - * for example on the COB2 command. - * Note that the name RexxStart, used later, is case-sensitive, - * and requires the PGMNAME(MIXED) compiler option. - ************************************************************* - IDENTIFICATION DIVISION. - ************************************************************* - PROGRAM-ID. 'CALLRexx' - AUTHOR. IBM VISUALAGE FOR COBOL. - - ************************************************************* - *NAME: CALLRexx *** - * *** - *FUNCTION: CALL A Rexx PROCEDURE NAME XXXXXXXX, *** - * PASSING ARGUMENT AND GETTING RETURNED DATA. *** - * *** - *EXTERNAL SUBROUTINES: NONE *** - *COPY MEMBERS: NONE *** - * *** - ************************************************************* - - ************************************************************* - ENVIRONMENT DIVISION. - ************************************************************* - CONFIGURATION SECTION. - - ************************************************************* - DATA DIVISION. - ************************************************************* - - WORKING-STORAGE SECTION. - - -</programlisting> -<programlisting> - ************************************************************* - * INTERNAL VARIABLES * - ************************************************************* - - 01 WS-WORK-FIELDS. - 05 WS-RESULT-AREA PIC X(255) VALUE SPACES. - 05 WS-ARGUMENT-AREA PIC X(255) VALUE SPACES. - 05 WS-PARM1 PIC X(50) VALUE '55'. - 05 WS-PARM2 PIC X(8) VALUE '66'. - 01 WS-RexxSTART-PARAMETERS. - 05 WS-Rexx-ARGUMENT-COUNT PIC S9(9) VALUE +1 COMP-5. - 05 WS-Rexx-ARGUMENT-LIST. - 10 WS-ARG-LENGTH PIC 9(9) COMP-5. - 10 WS-ARG-POINTER POINTER. - 05 WS-Rexx-PROGRAM-NAME PIC X(255) VALUE LOW-VALUES. - 05 WS-Rexx-ENV-NAME PIC X(20) VALUE LOW-VALUES. - 05 WS-Rexx-RETURN-CODE PIC S9(9) VALUE 0 COMP-5. - 05 WS-Rexx-RESULT. - 10 WS-RESULT-LENGTH PIC 9(9) COMP-5. - 10 WS-RESULT-POINTER POINTER. - 05 WS-Rexx-INTERPRETER-RC PIC S9(9) COMP-5. - - LINKAGE SECTION. - PROCEDURE DIVISION. - SET WS-ARG-POINTER TO ADDRESS OF WS-ARGUMENT-AREA. - MOVE LENGTH OF WS-ARGUMENT-AREA - TO WS-ARG-LENGTH. - STRING WS-PARM1 DELIMITED BY SPACE - ' ' DELIMITED BY SIZE - WS-PARM2 DELIMITED BY SPACE - INTO WS-ARGUMENT-AREA - END-STRING. - STRING 'MYCMD' DELIMITED BY SIZE - X'00' DELIMITED BY SIZE - INTO WS-Rexx-PROGRAM-NAME - END-STRING. - STRING 'CGISRV' DELIMITED BY SIZE - X'00' DELIMITED BY SIZE - INTO WS-Rexx-ENV-NAME - END-STRING. - SET WS-RESULT-POINTER TO - ADDRESS OF WS-RESULT-AREA. - MOVE LENGTH OF WS-RESULT-AREA TO WS-RESULT-LENGTH. - - -</programlisting> -<programlisting> - * Note that the name RexxStart is case sensitive - CALL 'RexxStart' USING - BY VALUE WS-Rexx-ARGUMENT-COUNT - BY REFERENCE WS-Rexx-ARGUMENT-LIST - BY REFERENCE WS-Rexx-PROGRAM-NAME - BY VALUE 0 - BY REFERENCE WS-Rexx-ENV-NAME - BY VALUE 0 - BY VALUE 0 - BY REFERENCE WS-Rexx-RETURN-CODE - BY REFERENCE WS-Rexx-RESULT - RETURNING WS-Rexx-INTERPRETER-RC. - DISPLAY WS-Rexx-RETURN-CODE ' ' WS-Rexx-INTERPRETER-RC. - DISPLAY WS-RESULT-LENGTH. - DISPLAY WS-RESULT-AREA. - GOBACK. -</programlisting> -</section> -</section> - -<section id="rexxwaitfortermfu"><title>The RexxWaitForTermination Function</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>invoking the Rexx interpreter</secondary> -<tertiary>RexxWaitForTermination</tertiary></indexterm> -<indexterm><primary>RexxWaitForTermination</primary></indexterm> -<para>RexxWaitForTermination waits for the termination of all activities of the -program that were started by RexxStart. This function puts your program into -a wait state. It cannot continue until the activities have finished.</para> -<programlisting> -RexxWaitForTermination(); -</programlisting> -</section> - -<section id="rexxdidtexxtermfu"><title>The RexxDidRexxTerminate Function</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>invoking the Rexx interpreter</secondary> -<tertiary>RexxDidRexxTerminate</tertiary></indexterm> -<indexterm><primary>RexxDidRexxTerminate</primary></indexterm> -<para>RexxDidRexxTerminate checks for the termination of all activities of the -program that were started by RexxStart, and allows your program to continue.</para> -<programlisting> -retc = RexxDidRexxTerminate(); -</programlisting> - -<section id="rexxdidrexxtermrc"><title>Return Codes</title> -<para></para> -<variablelist> -<varlistentry><term>0</term> -<listitem><para>Activities are still running. -</para></listitem></varlistentry> -<varlistentry><term>1</term> -<listitem><para>All activities have been terminated. -</para></listitem></varlistentry> -</variablelist> -</section> - -<section id="rexxdidrexxtermxmp"><title>Example</title> -<programlisting> -<![CDATA[ -while (!RexxDidRexxTerminate()) -{ - /* do your processing */ -} -]]> -</programlisting> -</section> -</section> -</section> - -<section id="subcom"><title>Subcommand Interface</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>subcommand interface</secondary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>description</secondary></indexterm> -<para>An application can create handlers to process commands from a Rexx program. -Once created, the subcommand handler name can be used with the RexxStart function -or the Rexx ADDRESS instruction. Subcommand handlers must be registered with -the RexxRegisterSubcomExe or RexxRegisterSubcomDll function before they are -used.</para> - -<section id="subinv"><title>Registering Subcommand Handlers</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>handler definitions</secondary></indexterm> -<para>A subcommand handler can reside in the same module (executable or DLL) -as an application, or it can reside in a separate dynamic-link library. -It is recommended that an application that runs Rexx procedures -<indexterm><primary>subcommand interface</primary> -<secondary>registering</secondary></indexterm> -with RexxStart uses RexxRegisterSubcomExe to register subcommand handlers. -The Rexx interpreter passes commands to the application subcommand handler -entry point. Subcommand handlers created with RexxRegisterSubcomExe are available -only to Rexx programs called from the registering application.</para> -<para>The RexxRegisterSubcomDll interface creates subcommand handlers that reside -in a dynamic-link library. Any Rexx program using the -Rexx ADDRESS instruction can access a dynamic-link library -subcommand handler. A dynamic-link library subcommand -handler can also be registered directly from a Rexx program using the RXSUBCOM -command.</para> - -<section id="createsubcomhandl"><title>Creating Subcommand Handlers</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>handler interface</secondary> -<tertiary>subcommand handler</tertiary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>definition</secondary></indexterm> -<para> The following example is a sample subcommand handler definition. </para> -<programlisting> -<![CDATA[ -ULONG APIENTRY command_handler( - PRXSTRING Command, /* Command string from Rexx */ - PUSHORT Flags, /* Returned Error/Failure flags */ - PRXSTRING Retstr); /* Returned RC string */ -]]> -</programlisting> -<para>where:</para> -<variablelist> -<varlistentry><term>Command</term> -<listitem><para>is the command string created by Rexx. </para> -<para><emphasis role="italic">command</emphasis> is a null-terminated -RXSTRING containing the issued command.</para> -</listitem></varlistentry> -<varlistentry><term>Flags</term> -<listitem><para>is the subcommand completion status. The subcommand handler can indicate -success, error, or failure status. The subcommand handler can set -<emphasis role="italic">Flags</emphasis> to one of the following values: -<variablelist> -<varlistentry><term>RXSUBCOM_OK</term> -<listitem><para>The subcommand completed normally. No errors occurred during subcommand -processing and the Rexx procedure continues when the subcommand handler returns. -</para></listitem></varlistentry> -<varlistentry><term>RXSUBCOM_ERROR -<indexterm><primary>subcommand interface</primary> -<secondary>subcommand errors</secondary></indexterm> -</term> -<listitem><para>A subcommand error occurred. RXSUBCOM_ERROR indicates a subcommand -error occurred; for example, incorrect command options or syntax.</para> -<para>If the -subcommand handler sets <emphasis role="italic">Flags</emphasis> to -RXSUBCOM_ERROR, the Rexx interpreter -raises an ERROR condition if SIGNAL ON ERROR or CALL ON ERROR traps have been -created. If TRACE ERRORS has been issued, Rexx traces the command when the -subcommand handler returns.</para> -</listitem></varlistentry> -<varlistentry><term>RXSUBCOM_FAILURE -<indexterm><primary>subcommand interface</primary> -<secondary>subcommand failures</secondary></indexterm> -</term> -<listitem><para>A subcommand failure occurred. RXSUBCOM_FAILURE indicates that general -subcommand processing errors have occurred. For example, unknown commands -usually return RXSUBCOM_FAILURE. </para> -<para>If the subcommand handler sets <emphasis role="italic">Flags</emphasis> -to RXSUBCOM_FAILURE, the Rexx interpreter raises a FAILURE condition -if SIGNAL ON FAILURE or CALL ON FAILURE traps have been created. If TRACE -FAILURES has been issued, Rexx traces the command when the subcommand handler -returns.</para> -</listitem></varlistentry> -</variablelist> -</para></listitem></varlistentry> -<varlistentry><term>Retstr -<indexterm><primary>subcommand interface</primary> -<secondary>subcommand return code</secondary></indexterm> -</term> -<listitem><para>is the address of an RXSTRING for the return code. It is a -character string return code that is assigned to the Rexx special variable -RC when the subcommand handler returns to Rexx. The Rexx interpreter provides -a default 256-byte RXSTRING in <emphasis role="italic">Retstr</emphasis>. -A longer RXSTRING can be allocated with -<computeroutput>GlobalAlloc(size)</computeroutput> if the return string is -longer than the default RXSTRING. If the subcommand handler sets -<emphasis role="italic">Retstr</emphasis> to an empty RXSTRING (a null -<emphasis role="italic">strptr</emphasis>), Rexx assigns the string 0 to RC. -</para></listitem></varlistentry> -</variablelist> - -<section id="subcomhandlxmp"><title>Example</title> -<indexterm><primary>subcommand interface</primary> -<secondary>subcommand handler example</secondary></indexterm> -<programlisting> -<![CDATA[ -ULONG APIENTRY Edit_Commands( - PRXSTRING Command, /* Command string passed from the caller */ - PUSHORT Flags, /* pointer too short for return of flags */ - PRXSTRING Retstr) /* pointer to RXSTRING for RC return */ -{ - LONG command_id; /* command to process */ - LONG rc; /* return code */ - PSZ scan_pointer; /* current command scan */ - PSZ target; /* general editor target */ - - scan_pointer = Command->strptr; /* point to the command */ - /* resolve command */ - command_id = resolve_command(&scan_pointer); - - switch (command_id) { /* process based on command */ - - case LOCATE: /* locate command */ - - /* validate rest of command */ - if (rc = get_target(&scan_pointer, &target)) { - *Flags = RXSUBCOM_ERROR; /* raise an error condition */ - break; /* return to Rexx */ - } - rc = locate(target); /* locate target in the file */ - *Flags = RXSUBCOM_OK; /* not found is not an error */ - break; /* finish up */ - -... - - default: /* unknown command */ - rc = 1; /* return code for unknown */ - *Flags = RXSUBCOM_FAILURE; /* this is a command failure */ - break; - } - - sprintf(Retstr->strptr, "%d", rc); /* format return code string */ - /* and set the correct length */ - Retstr->strlength = strlen(Retstr->strptr); - return 0; /* processing completed */ -} -]]> -</programlisting> -</section> -</section> -</section> - -<section id="rxxfin"><title>Subcommand Interface Functions</title> -<para>The following sections explain the functions for registering and using -subcommand handlers.</para> - -<section id="screg"><title>RexxRegisterSubcomDll</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>subcommand interface</secondary> -<tertiary>RexxRegisterSubcomDll</tertiary></indexterm> -<indexterm><primary>RexxRegisterSubcomDll</primary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>RexxRegisterSubcomDll</secondary></indexterm> -<para>RexxRegisterSubcomDll registers a subcommand handler that resides in -a dynamic-link library routine.</para> -<programlisting> -retc = RexxRegisterSubcomDll(EnvName, ModuleName, EntryPoint, - UserArea, DropAuth); -</programlisting> - -<section id="rexxregistersubcomdllparm"><title>Parameters</title> -<para></para> -<variablelist> -<varlistentry><term>EnvName (PSZ) - input</term> -<listitem><para>is the address of an ASCII subcommand handler name. -</para></listitem></varlistentry> -<varlistentry><term>ModuleName (PSZ) - input</term> -<listitem><para>is the address of an ASCII dynamic-link library -name. <emphasis role="italic">ModuleName</emphasis> is the DLL file containing -the subcommand handler routine. -</para></listitem></varlistentry> -<varlistentry><term>EntryPoint (PSZ) - input</term> -<listitem><para>is the address of an ASCII dynamic-link library -procedure name. <emphasis role="italic">EntryPoint</emphasis> is the name of -the exported routine within <emphasis role="italic">ModuleName</emphasis> -that Rexx calls as a subcommand handler. -</para></listitem></varlistentry> -<varlistentry><term>UserArea (PUCHAR) - input</term> -<listitem><para>is the address of an 8-byte area of user-defined information. The 8 -bytes <emphasis role="italic">UserArea</emphasis> addresses are saved with -the subcommand handler registration. <emphasis role="italic">UserArea</emphasis> -can be null if there is no user information to be saved. The -RexxQuerySubcom function can retrieve the saved user information. -</para></listitem></varlistentry> -<varlistentry><term>DropAuth (ULONG) - input</term> -<listitem><para>is the drop authority. -<emphasis role="italic">DropAuth</emphasis> identifies the processes that -can deregister the subcommand handler. The possible -<emphasis role="italic">DropAuth</emphasis> values are: -<variablelist> -<varlistentry><term>RXSUBCOM_DROPPABLE</term> -<listitem><para>Any process can deregister the subcommand handler with RexxDeregisterSubcom. -</para></listitem></varlistentry> -<varlistentry><term>RXSUBCOM_NONDROP</term> -<listitem><para>Only a -<indexterm><primary>thread</primary></indexterm> -thread within the same process as the thread that registered -the handler can deregister the handler with RexxDeregisterSubcom. -</para></listitem></varlistentry> -</variablelist> -</para></listitem></varlistentry> -</variablelist> -</section> - -<section id="rxsubcomrc"><title>Return Codes</title> -<informaltable frame="all"> -<tgroup cols="3"> -<colspec colnum="1" colwidth="4*"> -<colspec colnum="2" colwidth="1*"> -<colspec colnum="3" colwidth="5*"> -<tbody> -<row> -<entry>RXSUBCOM_OK</entry> -<entry>0</entry> -<entry>A subcommand has executed successfully.</entry> -</row> -<row> -<entry>RXSUBCOM_DUP</entry> -<entry>10</entry> -<entry>A duplicate handler name has been successfully registered. -There is either an executable handler with the same name registered in another -process, or a DLL handler with the same name registered in another DLL. (To -address this subcommand, you must specify its library name.)</entry> -</row> -<row> -<entry>RXSUBCOM_NOTREG</entry> -<entry>30</entry> -<entry>Registration was unsuccessful due to duplicate handler -and dynalink names (RexxRegisterSubcomExe or RexxRegisterSubcomDll); the subroutine -environment is not registered (other Rexx subcommand functions).</entry> -</row> -<row> -<entry>RXSUBCOM_NOEMEM</entry> -<entry>1002</entry> -<entry>There is insufficient memory available to complete this -request.</entry> -</row> -</tbody> -</tgroup> -</informaltable> -</section> - -<section id="rxsubcomremark"><title>Remarks</title> -<para><emphasis role="italic">EntryPoint</emphasis> can only be a 32-bit -routine.</para> -</section> -</section> - -<section id="screg2"><title>RexxRegisterSubcomExe</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>subcommand interface</secondary> -<tertiary>RexxRegisterSubcomExe</tertiary></indexterm> -<indexterm><primary>RexxRegisterSubcomExe</primary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>RexxRegisterSubcomExe</secondary></indexterm> -<para>RexxRegisterSubcomExe registers a subcommand handler that resides within -the application code.</para> -<programlisting> -retc = RexxRegisterSubcomExe(EnvName, EntryPoint, UserArea); -</programlisting> - -<section id="rxregsubcomparm"><title>Parameters</title> -<para></para> -<variablelist> -<varlistentry><term>EnvName (PSZ) - input</term> -<listitem><para>is the address of an ASCII subcommand handler name. -</para></listitem></varlistentry> -<varlistentry><term>EntryPoint (PFN) - input</term> -<listitem><para>is the address of the subcommand handler entry point within the -application executable code. -</para></listitem></varlistentry> -<varlistentry><term>UserArea (PUCHAR) - input</term> -<listitem><para>is the address of an 8-byte area of user-defined information. The 8 -bytes <emphasis role="italic">UserArea</emphasis> addresses are saved with -the subcommand handler registration. -<emphasis role="italic">UserArea</emphasis> can be null if there is no user -information to be saved. The RexxQuerySubcom function can retrieve the user -information. -</para></listitem></varlistentry> -</variablelist> -</section> - -<section id="rxsubcomregrc"><title>Return Codes</title> -<informaltable frame="all"> -<tgroup cols="3"> -<colspec colnum="1" colwidth="4*"> -<colspec colnum="2" colwidth="1*"> -<colspec colnum="3" colwidth="5*"> -<tbody> -<row> -<entry>RXSUBCOM_OK</entry> -<entry>0</entry> -<entry>A subcommand has executed successfully.</entry> -</row> -<row> -<entry>RXSUBCOM_DUP</entry> -<entry>10</entry> -<entry>A duplicate handler name has been successfully registered. - There is either an executable handler with the same name registered in another -process, or a DLL handler with the same name registered in another DLL. (To -address this subcommand, you must specify its library name.)</entry> -</row> -<row> -<entry>RXSUBCOM_NOTREG</entry> -<entry>30</entry> -<entry>Registration was unsuccessful due to duplicate handler -and dynalink names (RexxRegisterSubcomExe or RexxRegisterSubcomDll); the subroutine -environment is not registered (other Rexx subcommand functions).</entry> -</row> -<row> -<entry>RXSUBCOM_NOEMEM</entry> -<entry>1002</entry> -<entry>There is insufficient memory available to complete this -request.</entry> -</row> -</tbody> -</tgroup> -</informaltable> -</section> - -<section id="rxsubcomregremark"><title>Remarks</title> -<para>If <emphasis role="italic">EnvName</emphasis> -is the same as a subcommand handler already registered -with RexxRegisterSubcomDll, RexxRegisterSubcomExe returns RXSUBCOM_DUP. -This is not an error condition. It means that RexxRegisterSubcomExe has successfully -registered the new subcommand handler.</para> -<para>A Rexx procedure can register dynamic-link library -subcommand handlers with the RXSUBCOM command. For example: </para> -<programlisting> -<![CDATA[ - /* register Dialog Manager */ - /* subcommand handler */ -"RXSUBCOM REGISTER ISPCIR ISPCIR ISPCIR" -Address ispcir /* send commands to dialog mgr */ -]]> -</programlisting> -<para>The RXSUBCOM command registers the Dialog Manager subcommand handler ISPCIR -as routine ISPCIR in the ISPCIR dynamic-link library.</para> -</section> - -<section id="rxsubcomregxmp"><title>Example</title> -<indexterm><primary>RexxStart</primary> -<secondary>exit example</secondary></indexterm> -<programlisting> -<![CDATA[ -WORKAREARECORD *user_info[2]; /* saved user information */ - -user_info[0] = global_workarea; /* save global work area for */ -user_info[1] = NULL; /* re-entrance */ - -rc = RexxRegisterSubcomExe("Editor", /* register editor handler */ - &Edit_Commands, /* located at this address */ - user_info); /* save global pointer */ - -]]> -</programlisting> -</section> -</section> - -<section id="scdrp"><title>RexxDeregisterSubcom</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>subcommand interface</secondary> -<tertiary>RexxDeregisterSubcom</tertiary></indexterm> -<indexterm><primary>RexxDeregisterSubcom</primary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>RexxDeregisterSubcom</secondary></indexterm> -<para>RexxDeregisterSubcom deregisters a subcommand handler.</para> -<programlisting> -retc = RexxDeregisterSubcom(EnvName, ModuleName); -</programlisting> - -<section id="rxderegsubcomparm"><title>Parameters</title> -<para></para> -<variablelist> -<varlistentry><term>EnvName (PSZ) - input</term> -<listitem><para>is the address of an ASCII subcommand handler name. -</para></listitem></varlistentry> -<varlistentry><term>ModuleName (PSZ) - input</term> -<listitem><para>is the address of an ASCII dynamic-link library -name. <emphasis role="italic">ModuleName</emphasis> -is the name of the dynamic-link library containing the registered -subcommand handler. When <emphasis role="italic">ModuleName</emphasis> -is null, RexxDeregisterSubcom searches the RexxRegisterSubcomExe subcommand -handler list for a handler within the current process. If RexxDeregisterSubcom -does not find a RexxRegisterSubcomExe handler, it searches the RexxRegisterSubcomDll -subcommand handler list. -</para></listitem></varlistentry> -</variablelist> -</section> - -<section id="rxderegsubcomrc"><title>Return Codes</title> -<informaltable frame="all"> -<tgroup cols="3"> -<colspec colnum="1" colwidth="4*"> -<colspec colnum="2" colwidth="1*"> -<colspec colnum="3" colwidth="5*"> -<tbody> -<row> -<entry>RXSUBCOM_OK</entry> -<entry>0</entry> -<entry>A subcommand has executed successfully.</entry> -</row> -<row> -<entry>RXSUBCOM_NOTREG</entry> -<entry>30</entry> -<entry>Registration was unsuccessful due to duplicate handler -and dynalink names (RexxRegisterSubcomExe or RexxRegisterSubcomDll); the subroutine -environment is not registered (other Rexx subcommand functions).</entry> -</row> -<row> -<entry>RXSUBCOM_NOCANDROP</entry> -<entry>40</entry> -<entry>The subcommand handler has been registered as "not -droppable."</entry> -</row> -</tbody> -</tgroup> -</informaltable> -</section> - -<section id="rxderegsubcomremark"><title>Remarks</title> -<para>The handler is removed from the active subcommand handler list.</para> -</section> -</section> - -<section id="scqry"><title>RexxQuerySubcom</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>subcommand interface</secondary> -<tertiary>RexxQuerySubcom</tertiary></indexterm> -<indexterm><primary>RexxQuerySubcom</primary></indexterm> -<indexterm><primary>subcommand interface</primary> -<secondary>RexxQuerySubcom</secondary></indexterm> -<para>RexxQuerySubcom -queries a subcommand handler and retrieves saved user information.</para> -<programlisting> -retc = RexxQuerySubcom(EnvName, ModuleName, Flag, UserWord); -</programlisting> - -<section id="rxquerysubcomparm"><title>Parameters</title> -<para></para> -<variablelist> -<varlistentry><term>EnvName (PSZ) - input</term> -<listitem><para>is the address of an ASCII subcommand handler name. -</para></listitem></varlistentry> -<varlistentry><term>ModuleName (PSZ) - input</term> -<listitem><para>is the address of an ASCII dynamic-link library -name. <emphasis role="italic">ModuleName</emphasis> restricts the query to a -subcommand handler within -the <emphasis role="italic">ModuleName</emphasis> dynamic-link library. When -<emphasis role="italic">ModuleName</emphasis> is null, RexxQuerySubcom -searches the RexxRegisterSubcomExe -subcommand handler list for a handler within the current process. If RexxQuerySubcom -does not find a RexxRegisterSubcomExe handler, it searches the RexxRegisterSubcomDll -subcommand handler list. -</para></listitem></varlistentry> -<varlistentry><term>Flag (PUSHORT) - output</term> -<listitem><para>is the subcommand handler registration flag. -<emphasis role="italic">Flag</emphasis> is the -<emphasis role="italic">EnvName</emphasis> subcommand handler registration -status. When RexxQuerySubcom -returns RXSUBCOM_OK, the <emphasis role="italic">EnvName</emphasis> -subcommand handler is currently -registered. When RexxQuerySubcom returns RXSUBCOM_NOTREG, the -<emphasis role="italic">EnvName</emphasis> subcommand handler is not registered. -</para></listitem></varlistentry> -<varlistentry><term>UserWord (PUCHAR) - output</term> -<listitem><para>is the address of an 8-byte area that receives the user information -saved with RexxRegisterSubcomExe or RexxRegisterSubcomDll. -<emphasis role="italic">UserWord</emphasis> can -be null if the saved user information is not required. -</para></listitem></varlistentry> -</variablelist> -</section> - -<section id="rxquerysubcomrc"><title>Return Codes</title> -<informaltable frame="all"> -<tgroup cols="3"> -<colspec colnum="1" colwidth="4*"> -<colspec colnum="2" colwidth="1*"> -<colspec colnum="3" colwidth="5*"> -<tbody> -<row> -<entry>RXSUBCOM_OK</entry> -<entry>0</entry> -<entry>A subcommand has executed successfully.</entry> -</row> -<row> -<entry>RXSUBCOM_NOTREG</entry> -<entry>30</entry> -<entry>Registration was unsuccessful due to duplicate handler -and dynalink names (RexxRegisterSubcomExe or RexxRegisterSubcomDll); the subroutine -environment is not registered (other Rexx subcommand functions).</entry> -</row> -</tbody> -</tgroup> -</informaltable> -</section> - -<section id="rxquerysubcomxmp"><title>Example</title> -<programlisting> -<![CDATA[ -ULONG APIENTRY Edit_Commands( - PRXSTRING Command, /* Command string passed from the caller */ - PUSHORT Flags, /* pointer too short for return of flags */ - PRXSTRING Retstr) /* pointer to RXSTRING for RC return */ -{ - WORKAREARECORD *user_info[2]; /* saved user information */ - WORKAREARECORD global_workarea; /* application data anchor */ - USHORT query_flag; /* flag for handler query */ - - - rc = RexxQuerySubcom("Editor", /* retrieve application work */ - NULL, /* area anchor from Rexx */ - &query_flag, - user_info); - - global_workarea = user_info[0]; /* set the global anchor */ -]]> -</programlisting> -</section> -</section> -</section> -</section> - -<section id="os2xfun"><title>External Function Interface</title> -<indexterm><primary>application programming interfaces</primary> -<secondary>external function interface</secondary></indexterm> -<indexterm><primary>external function interface</primary> -<secondary>description</secondary></indexterm> -<para>There are two types of Rexx external functions: </para> -<itemizedlist> -<listitem><para>Routines written in Rexx</para></listitem> -<listitem><para>Routines written in other Windows-supported languages -</para></listitem></itemizedlist> -<para>External functions written in Rexx do not need to be registered. These -functions are found by a disk search for a Rexx procedure file that matches -the function name.</para> - -<section id="xffmt"><title>Registering External Functions</title> -<para>An external function can reside in the same module (executable -or DLL) -as an application, or in a separate dynamic-link library. -RexxRegisterFunctionExe registers external functions within an application -module. External functions registered with RexxRegisterFunctionExe are available -only to Rexx programs called from the registering application.</para> -<para>The RexxRegisterFunctionDll interface registers external functions that -reside in a dynamic-link library. Any Rexx program can -access such an external function after it is registered. It can also be registered -directly from a Rexx program using the Rexx RXFUNCADD built-in function.</para> - -<section id="xffmtc"><title>Creating External Functions</title> -<indexterm><primary>external function interface</primary> -<secondary>writing</secondary></indexterm> -<para>The following is a sample external function definition:</para> -<programlisting> -<![CDATA[ -ULONG APIENTRY SysLoadFuncs( - PSZ Name, /* name of the function */ - LONG Argc, /* number of arguments */ - RXSTRING Argv[], /* list of argument strings */ - PSZ Queuename, /* current queue name */ - PRXSTRING Retstr) /* returned result string */ -]]> -</programlisting> -<para>where:</para> -<variablelist> -<varlistentry><term>Name</term> -<listitem><para>is the address of an ASCII function name used to call the -external function. -</para></listitem></varlistentry> -<varlistentry><term>Argc</term> -<listitem><para>is the number of elements in the -<emphasis role="italic">Argv</emphasis> array. -<emphasis role="italic">Argv</emphasis> contains -<emphasis role="italic">Argc</emphasis> RXSTRINGs. -</para></listitem></varlistentry> -<varlistentry><term>Argv</term> -<listitem><para>is an array of null-terminated RXSTRINGs for the function arguments. -</para></listitem></varlistentry> -<varlistentry><term>Queuename</term> -<listitem><para>is the name of the currently defined external Rexx data queue. -</para></listitem></varlistentry> -<varlistentry><term>Retstr</term> -<listitem><para>is the address of an RXSTRING for the returned value. -<emphasis role="italic">Retstr</emphasis> is -a character string function or subroutine return value. When a Rexx program -calls an external function with the Rexx CALL instruction, -<emphasis role="italic">Retstr</emphasis> is -assigned to the special Rexx variable RESULT. When the Rexx program calls -an external function with a function call, -<emphasis role="italic">Retstr</emphasis> is used directly -within the Rexx expression.</para> -<para>The Rexx interpreter provides a default 256-byte -RXSTRING in <emphasis role="italic">Retstr</emphasis>. A longer RXSTRING -can be allocated with <computeroutput>GlobalAlloc(size)</computeroutput> -if the returned string is longer than 256 bytes. -The Rexx interpreter releases <emphasis role="italic">Retstr</emphasis> with -<computeroutput>GlobalFree(ptr)</computeroutput> when -the external function completes.</para> -</listitem></varlistentry> -<varlistentry><term>Returns -<indexterm><primary>external function interface</primary> -<secondary>returned results</secondary></indexterm> -</term> -<listitem><para>is an integer return code from the function. When the external function -returns <computeroutput>0</computeroutput>, the function completed successfully. -<emphasis role="italic">Retstr</emphasis> contains -the return value. When the external function returns a nonzero return code, -the Rexx interpreter raises Rexx error 40, "Incorrect call to routine". -The <emphasis role="italic">Retstr</emphasis> value is ignored. </para> -<para>If the external function does not -have a return value, the function must set -<emphasis role="italic">Retstr</emphasis> to an empty RXSTRING -(null <emphasis role="italic">strptr</emphasis>). When an external function -called as a function does not return a value, the interpreter raises error 44, -"Function or message did not return data". When an external function -called with the Rexx CALL instruction does not return a value, the Rexx -interpreter drops (unassigns) the special variable RESULT.</para> -</listitem></varlistentry> -</variablelist> -</section> -</section> - -<section id="xfclg"><title>Calling External Functions</title> -<para>RexxRegisterFunctionExe external functions are local to the registering -process. Another process can call the RexxRegisterFunctionExe to make these -functions local to this process. RexxRegisterFunctionDll functions, however, -are ava... [truncated message content] |