The procedure in this example follows the 4-step sequence outlined above.
The Hello module appends an input string to "hello." The resulting combination is the module's output. If the input string is NULL, the default output is "hello world."
Data Explorer's graphical user interface and executive access the module description file to determine the names of the modules and their inputs and outputs.
Note: | This type of file is commonly referred to as an "mdf" file (because of its file extension) and is created automatically from user input to the Module Builder, as described in Chapter 3. "Module Builder". However, for very simple modules like the one in this example, it is usually easier and quicker to create the file with a text editor. |
Parameter names are a part of the module interface that can be seen by the user. In the graphical user interface, parameter names appear in the configuration dialog box and also serve as default names for interactors. In the scripting language, module parameters can be specified by name.
A new module cannot have the name of an existing Data Explorer module (see IBM Visualization Data Explorer User's Reference for a complete list). You should also be aware of the following requirements:
In the following example, the mdf file consists of five statements:
MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string
For details, see 11.1 , "Module Description Files".
Having defined the module in a description file, you can now implement the module with a C-language function like the one shown here.
01 #include <dx/dx.h> 02 03 04 Error m_Hello(Object *in, Object *out) 05 { 06 char message[30], *greeting; 07 08 if (!in[0]) 09 sprintf(message, "hello world"); 10 else { 11 DXExtractString(in[0], &greeting); 12 sprintf(message, "%s %s", "hello", greeting); 13 } 14 15 out[0] = DXNewString(message); 16 return OK; 17 }
The dx.h file "included" in line 01 contains the definitions of all the Data Explorer library routines. The name of the function that implements a module must consist of the module name (specified in the MODULE statement of the description file) prefixed by m_. In this case, the function name is m_Hello.
When Data Explorer invokes a module, it passes the module two pointers: the first to an array containing the inputs, the second to an array containing the outputs. (See 4.3 , "Data Explorer Execution Model" for details of parameter passing.)
Because the input parameter of this module is passed to m_Hello as an array of pointers, in[0] is the value parameter. If no argument is specified for value, in[0] is NULL, and the default output ("hello world") is placed in message. If you do specify an argument, a library routine (DXExtractString) extracts it from in[0], and greeting becomes a pointer to that string. In line 12, greeting is appended to "hello," creating message.
Once message has been created, the DXNewString library routine creates a String Object for the output out[0].
Note: The output of any Data Explorer module must be a Data Explorer Object (such as an Array, Field, or Group). See Table 1 for a complete list of Data Explorer Objects.
Copy the following files to the directory you want to work in:
/usr/local/dx/samples/program_guide/Makefile_workstation /usr/local/dx/samples/program_guide/hello.c /usr/local/dx/samples/program_guide/hello.mdfNow rename the makefile to Makefile (the name of the default makefile) and enter: make hello. This command creates an executable that contains the Hello module.
To invoke this executable (from the directory to which the files were copied), enter:
dx -mdf ./hello.mdf -exec ./dxexec.This command starts Data Explorer (the hello.mdf file tells the graphical user interface about Hello and its inputs and outputs).
You can now run any visual program that uses the Hello module. One such program is hello.net in the directory /usr/local/dx/samples/program_guide.
Copy the following files to the directory you want to work in:
/usr/local/dx/samples/program_guide/Makefile_workstation /usr/local/dx/samples/program_guide/hello.c /usr/local/dx/samples/program_guide/hello_outboard.mdfNow rename the makefile to Makefile (the name of the default makefile) and enter: make hello_outboard. This command creates the executable hello_outboard.
To invoke the executable (from the directory to which the files were copied), enter:
dx -mdf ./hello_outboard.mdfThis command starts Data Explorer (the hello_outboard.mdf file tells the graphical user interface about Hello and its inputs and outputs).
You can now run any visual program that uses the Hello module. One such program is hello.net in the directory /usr/local/dx/samples/program_guide.
Note: The mdf file of the outboard module contains one additional statement, OUTBOARD, which specifies the executable (hello_outboard; see 11.1 , "Module Description Files"). This statement may also specify the name of a host on which to run the executable.
MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string OUTBOARD hello_outboard INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string
Copy the following files to the directory you want to work in:
/usr/local/dx/samples/program_guide/Makefile_workstation /usr/local/dx/samples/program_guide/hello.c /usr/local/dx/samples/program_guide/hello_loadable.mdfNow rename the makefile to Makefile (the name of the default makefile) and enter: make hello_loadable. This command creates the executable hello_loadable.
Note: Runtime-loadable modules are not available for SunOS 4.1 or Data General AViiON.
To invoke the executable (from the directory to which the files were copied), enter:
dx -mdf ./hello_loadable.mdfThis command starts Data Explorer (the hello_loadable.mdf file tells the graphical user interface about Hello and its inputs and outputs).
You can now run any visual program that uses the Hello module. One such program is hello.net in the directory /usr/local/dx/samples/program_guide.
Note: The mdf file of the runtime-loadable module contains one additional statement, LOADABLE, which specifies the executable (hello_loadable; see 11.1 , "Module Description Files").
MODULE Hello CATEGORY Greetings DESCRIPTION Prefixes "hello" to the input string LOADABLE hello_loadable INPUT value; string; "world"; input string OUTPUT greeting; string; prefixed string
In this example (Figure 2), the Hello module is not given an input value and therefore uses its default string ("hello world") as output. The Echo module sends the string to Data Explorer's Message window.
Figure 2. The Hello
Module in a Visual Program. The protrusion of the upper tab indicates
that the Hello module is using default input. When input is supplied through a
connecting "arc," as it is to the Echo module, the input tab folds in.
A visual program that produces the string "hello, how are you?" can be created by:
Figure 3. The Hello
Module with a String Interactor in a Visual Program. Note that both
input tabs are folded in (compare Figure 2).
In the following example, no input to Hello is provided, so the module produces its default output:
a = Hello(); Echo(a);
In the next three examples, the user provides input to the Hello module. All three produce the output "hello, how are you?"
Example 1
b = Hello(", how are you?"); Echo(b);Example 2
b = Hello(value = ", how are you?"); Echo(b);
Example 3
a = ", how are you?"; b = Hello(a); Echo(b);
The definition of the Hello module (see 2.2 , "Adding the Hello Module") contains no error checking code. This omission, of course, is not a recommended practice. In the following version, the Data Explorer routine DXSetError reports errors to the user.
01 #include <dx/dx.h> 02 03 04 m_HelloErrorChecking(Object *in, Object *out) 05 { 06 char message[30], *greeting, longmessage=NULL; 07 08 if (!in[0]) { 09 sprintf(message, "hello world"); 10 out[0] = DXNewString(message); 11 }
12 else { 13 if (!DXExtractString(in[0], &greeting)) { 14 DXSetError(ERROR_BAD_PARAMETER, "value must be a string"); 15 goto error; 16 } 17 if (strlen(greeting)<=(28-strlen("hello")) { 18 sprintf(message, "%s %s", "hello", greeting); 19 out[0] = DXNewString(message); 20 }
21 else { 22 longmessage = DXAllocate((strlen("hello")+strlen(greeting)+2) * sizeof(char)); 23 if (!longmessage) 24 goto error; 25 sprintf(longmessage, "%s %s", "hello", greeting); 26 out[0] = DXNewString(longmessage); 27 DXFree((Pointer)longmessage); 28 } 29 }
30 return OK; 31 32 error: 33 DXFree((Pointer)longmessage); 34 return ERROR; 35 }
In this example, the return from DXExtractString (line 13) is checked. If the routine returns ERROR, the error message "value must be a string" is generated and Hello returns ERROR.
The combined length of the user-supplied parameter string and "hello" is checked against the length of the buffer. If it exceeds the length, a new buffer is allocated for the output message (and freed before returning). Because longmessage is initialized to NULL, it can safely be freed on error, even if it has not yet been allocated.
Note: The m_module function should return an error code according to the Data Explorer library standard: ERROR for error and OK for successful completion. Thus the module entry point would typically be declared by:
Error m_module(Object *in, Object *out);
To create a version of Data Explorer that includes the HelloErrorChecking module, copy the following files to the directory you want to work in:
/usr/local/dx/samples/program_guide/Makefile_workstation /usr/local/dx/samples/program_guide/hello_errorchecking.c /usr/local/dx/samples/program_guide/helloerr.mdfNow rename the makefile to Makefile (the name of the default makefile) and enter: make helloerr. This command creates an executable that contains the HelloErrorChecking module.
To invoke this executable (from the directory to which the files were copied), enter:
dx -mdf ./helloerr.mdf -exec ./dxexec.This command starts Data Explorer (the helloerr.mdf file tells the graphical user interface about HelloErrorChecking and its inputs and outputs).
You can now run any visual program that uses the HelloErrorChecking module. One such program is hello_errorchecking.net in the /usr/local/dx/samples/program_guide directory.