call-object-handle :attribute :methodA method of the call object. The methods let you set parameters, reset attributes to their default values, and invoke the call object.
The following fragment dynamically invokes an external procedure persistently, then dynamically invokes one of its internal procedures:
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.CREATE CALL hCall./* Invoke hello.p non-persistently */ASSIGNhCall:CALL-NAME = "hello.p"hCall:NUM-PARAMETERS = 1.hCall:SET-PARAMETER(1, "CHARACTER", "INPUT", "HELLO WORLD").hCall:INVOKE./* Reset the call object handle */hCall:CLEAR./* Invoke persis.p persistently */ASSIGNhCall:CALL-NAME = "persis.p"hCall:PERSISTENT = TRUE./* IN-HANDLE automatically set to the handle of the persistent procedure */hCall:INVOKE./* Invoke internal-persis-proc in persis.p */ASSIGNhCall:CALL-NAME = "internal-persis-proc"hCall:NUM-PARAMETERS = 1.hCall:SET-PARAMETER( 1, "INTEGER", "INPUT", 333).hCall:INVOKE./* Clean up */DELETE PROCEDURE hCall:IN-HANDLE.DELETE OBJECT hCall.
/* Get title of frame */ASSIGNhCall:IN-HANDLE = myframe_handlehCall:CALL-TYPE = GET-ATTR-CALL-TYPEhCall:CALL-NAME = "TITLE".hCall:INVOKE.Mytitle = hCall:RETURN-VALUE.
/* Set SESSION:NUMERIC-FORMAT to "european" */ASSIGNhCall:IN-HANDLE = "session"hCall:CALL-TYPE = SET-ATTR-CALL-TYPEhCall:CALL-NAME = "numeric-format"hCall:NUM-PARAMETERS = 1.hCall:SET-PARAMETER( 1, "CHAR", "INPUT", "european").hCall:INVOKE.The following fragment drives the call object’s INVOKE( ) method from a TEMP-TABLE:
/* Suppose hRuntt is a temp-table that has one record with the following fields:parm_1parm_2...parm_nrun-namenparmsdatatypes, extent nparmsiomodes, extent nparms */DEFINE INPUT PARAMETER TABLE-HANDLE hRuntt.DEFINE VARIABLE hDtypes AS HANDLE NO-UNDO.DEFINE VARIABLE hIOmodes AS HANDLE NO-UNDO.DEFINE VARIABLE hCall AS HANDLE NO-UNDO.DEFINE VARIABLE ix AS INTEGER NO-UNDO.ASSIGNhDtypes = hRuntt:BUFFER-FIELD("datatypes")hIOmodes = hRuntt:BUFFER-FIELD("iOmodes").hRuntt:FIND-FIRST.CREATE CALL hCall.ASSIGNhCall:CALL-NAME = hRuntt:BUFFER-FIELD("run-name"):BUFFER-VALUEhCall:NUM-PARAMETERS = hRuntt:BUFFER-FIELD("nparms"):BUFFER-VALUE.FOR ix = 1 to hCall:NUM-PARAMETERS.hCall:SET-PARAMETER(ix, hDtypes:BUFFER-VALUE(ix),hIOmodes:BUFFER-VALUE(ix), hRuntt:BUFFER-FIELD(ix):BUFFER-VALUE).END.hCall:INVOKE.DELETE OBJECT hCall./* If there are output parms, get values from hRuntt:BUFFER-FIELD(ix) */The following fragment implements an ABL function, sleep, which causes the AVM to sleep for a specified number of milliseconds:
FUNCTION sleep RETURNS INTEGER (INPUT msecs AS INTEGER):DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO INITIAL "sleep".DEFINE VARIABLE cLibrary AS CHARACTER NO-UNDO INITIAL "libc.so.1".DEFINE VARIABLE hCall AS HANDLE NO-UNDO.CREATE CALL hCall.ASSIGNcLibrary = "kernel32.dll" WHEN OPSYS = "WIN32"cFunction = "Sleep" WHEN OPSYS = "WIN32"hCall:CALL-NAME = cFunctionhCall:LIBRARY = cLibraryhCall:CALL-TYPE = DLL-CALL-TYPEhCall:NUM-PARAMETERS = 1.hCall:SET-PARAMETER(1, "LONG", "INPUT", msecs).hCall:INVOKE( ).DELETE OBJECT hCall.RETURN msecs.END FUNCTION.Note that the code checks to determine on which OS it is running, and invokes the appropriate Windows DLL or UNIX shared library.
![]()
Invoking logic dynamically requires many more lines of code and is less efficient than invoking it statically. You typically use the call object when you cannot use the RUN statement, the DYNAMIC-FUNCTION() function, or widget:attribute or widget:method syntax, as in the following situations:
![]()
To invoke an internal or external procedure whose calling sequence (number of parameters and the data type of each) is unknown at compile time.
Note: If only the name of the procedure is unknown at compile time, use the RUN statement with the VALUE option—and avoid the call object altogether.
Note: If only the name of the function is unknown at compile time, use the DYNAMIC-FUNCTION() function—and avoid the call object altogether.If you already know the name of the attribute or procedure, you know its syntax, since the name implies certain syntax. And if you know the syntax, you know the calling sequence, since the syntax defines the calling sequence. And if you know the calling sequence, you can use widget:attribute or widget:method syntax—and avoid the call object altogether.
CREATE object-handle IN widget-pool
CREATE CALL hCall.
Note: Unlike most ABL objects, the call object, by default, goes into the SESSION widget pool, not into the closest unnamed widget pool.
DELETE OBJECT handle.
DELETE OBJECT hCall.Since the call object, by default, goes into the SESSION widget pool, not into the closest unnamed widget pool, to delete a call object created when the IN widget-pool option is not used, use the DELETE OBJECT handle syntax explicitly.
© 2012 Progress Software Corporation and/or its subsidiaries or affiliates. |