Copyright: Copyright (c) 1997 Hewlett-Packard


Introduction

The “Callable” VEE Custom Control (hereafter referred to as “the OCX”) is an extension of the “C to VEE” RPC mechanism that provides OLE Automation server capabilities through the use of an OLE Custom Control (OCX).  The OCX presents visual and programmatic interfaces that allow control containers and OLE-Automation-aware applications to call VEE User Functions.

The OCX takes advantage of the distributed nature inherent in C to VEE RPC’s.  The called VEE function may run on any networked workstation that has VEE or VEE RunTime installed, including the workstation running the application which uses the OCX.  The server workstation may be any type of computer capable of running HP VEE 3.2 or later.

The OCX is installed with the Windows 95(tm) and Windows NT(tm) versions of the HP VEE and HP VEE RunTime products.  The installation program performs all actions necessary to register the OCX on each system on which you install HP VEE.  The OCX is installed in your system directory and is named “call.ocx”.

What You Need to Use the Callable VEE OCX.

Reference.

Glossary


Visual Interface

Figure 1: The OCX Visual Interface

Referring to the screen shot above, the OCX visual interface is composed of a number of interactive controls that allow you to change some attribute and a number of controls that provide informational displays.

In the upper left corner, there is a button labeled “Browse…”.  Pressing this button presents a “File Open” dialog that allows you to browse through HP VEE library files, looking for the functions you wish to call.  You may choose any library file that the file dialog presents, including files found on workstations other than the one running the OCX.  Once you have selected a library file, the OCX will load the file, and present information describing the functions found in that library.

Moving down along the left of the visual interface, you will find an editable entry field with a label titled “Library Path:”.  This type-in field allows you select the library of functions you want to load if you don’t want to use the “Browse…” button.  You might want to do this if the workstation that will be running the functions is an HP-UX machine.  When you select a file using the file dialog, this editing field gets updated to reflect that selection.

Further down along the left edge is an editable field labeled “Host Name:”.  An entry in this field tells the OCX which workstation you wish to run your functions on.  You may enter the human-readable host name, as shown above, or use the fully-qualified IP address, e.g. 15.11.90.16.

It is important to remember that the library file you select is relative to the file system on the workstation that will execute your HP VEE function.  If you specify a path of “d:\my files\test.vee”, for instance, the OCX will try to execute this function by looking at the file system on the workstation identified in the “Host Name” property.

The next control down is a check box labeled “Debug”.  Checking this control causes your HP VEE function to run in a mode that allows you to debug the HP VEE function.  What this means in practice is that, when your HP VEE function runs, an HP VEE window gets mapped with the function paused at the first executable object.  You may then step through the function and use any of the debugging features you would use when debugging a local program.

To the right of the “Browse…” button, you will find a list box labeled “Functions:”  This field contains all of the functions defined in the HP VEE library file identified in the “Library Path:” field.  Selecting one of the entries causes the information associated with the newly-selected function to display itself in the “Data Pin Information:” and “Description Text:” fields.

The “Data Pin Information:” field lists the input and output pin information for the selected function.  The input pin information contains the pin name as well as the type of data you should supply to this pin when calling the function.  The output pin information contains only the pin names, because output terminal will have no data type information until after the function executes.


Example Session

We will use Visual Basic(tm) as the application which illustrates the use of the OCX.  The example that follows will call a simple User Function that returns a random number between an upper and lower bound; both of which are User Function data terminals.  The HP VEE function is illustrated below.

Figure 2: ‘Random’ Function Detail View

Figure 3: ‘Random’ Function Panel View

Figure 4: ‘Random’ Function Properties

The preceding illustration depicts the User Function Properties dialog.  We want to draw your attention the group box labeled ‘Pop-Up Panel’.  This group contains a check box labeled ‘Show Panel On Execute’.  Notice that we have checked this selection.  In a User Function that has an interactive Panel, (either to present information or to allow the program user to enter data) the function will not finish executing until the program user has fiddled with all the interactive controls.  If we were to leave the above-referenced check box in its cleared state, the function would not make the panel visible; thereby preventing the user from interacting with the controls and preventing the function from finishing.  In this case, the OK button requires interactive fiddling.

If your function has no interactive requirements, you need not create a panel at all.  If the User Function has no panel, it will execute without showing an interactive window.

Our Basic program will contain three controls: the Callable VEE OCX; a push button; and a text field.  When you push the button, we will instruct the OCX to load a library containing our ‘Random’ function, construct arguments, call the function, then retrieve and display the result.

The end result of our program (after pushing the button we added to the form) is shown below:

Figure 5: The End Result

Listing 1 is the program we wrote for this example.  All of the functionality is contained in the push button’s click handler function (shown in the listing below).

Private Sub Command1_Click()

Dim args(2)	' This HP VEE function has 2

' data input pins, so we create

' an array 2 elements long.  Each

' element will hold the value passed

' to an input pin.  The values are

' passed positionally; the

' lowest-number element corresponds

' to the top-most data pin.

' assumes Option Base 1

Dim returns(1)	' The number of retun values from an

' HP VEE User Function is not known

' until the function executes.  We

' create a variable whose contents

' we can change dynamically.

Dim FunctionReturn As Double	' We know, in this case, that our

' HP VEE User Function returns a

' scalar double value.

LibName = "\tmp\random.vee"	' Our HP VEE library file.

FunctionName = "Rand"	' The function we want to call.  The

' function name is case sensitive.

args(1) = 1	' lower bound; first data pin

args(2) = 10	' upper bound; second data pin

result = Call1.LoadVeeLibrary(LibName)	' load the library

result = Call1.CallFunction(LibName, FunctionName, args)

' call the function

returns(1) = FunctionReturn	' reserve space for a scalar double

' return value from our HP VEE

' function

result = Call1.RetrieveFunctionResults(LibName, FunctionName,

returns)	' get the results

Text1.Text = returns(1)	' display the results

End Sub

Listing 1: Our Example Session Program

One important point to mention is that all of the programs we use in this help file assume that the size of any array you create will hold only the number of elements you specifically requested.  For most flavors of Basic, this means that you should specify ‘Option Base 1’ for your program.

When you click the ‘Execute Function’ button, an HP VEE window like the Figure 6 will pop up.  The HP VEE server process will map its window when a function displays a panel.

Figure 6: The HP VEE Server Window

Should the program user check the ‘Debug’ selection on the OCX visual interface, the HP VEE server process will map a window like that shown in Figure 7.  The HP VEE server process will show the User Function’s edit window with the server paused at the first executable object.  You may then use all of HP VEE’s debugging tools.  Note that the HP VEE server process will always map a window when the OCX is in ‘Debug’ mode, even if the associated User Function does not have a panel.

Figure 7: The HP VEE Server in Debug Mode


What You Need to Use the Callable VEE OCX

The client workstation (the computer running an application which will embed the OCX) needs the following components:

•	TCP/IP network protocol:  Your workstation will need a host name that is unique in its domain and a valid IP address.

•	Correctly registered Callable VEE OCX:  If the client workstation has HP VEE installed, no further configuration is necessary.  If you will be moving the OCX to a Windows 95(tm) or Windows NT(tm) workstation that doesn’t have VEE installed, you will need to manually configure it.

•	Control container application:  To use the OCX, you will need an application that is capable of containing an OCX and that is capable of participating in an OLE Automation conversation.  All of the examples in this help file use Microsoft’s(tm) Visual Basic(tm) as a control container.

The server workstation (the workstation on which the called VEE function will execute) needs the following components:

•	VEE Service Manager:  Windows 95(tm) and Windows NT(tm) versions of VEE include an executable named “veesm.exe” in the VEE installation directory.  That executable must be running on the server for a client workstation to call VEE functions on the server workstation.  The most common configuration is to include veesm.exe as a Program Manager icon or shortcut in your “Startup” group.  If the server is an HP-UX workstation, the HP VEE installation process configures your inet daemon automatically.  There is no equivalent to the veesm executable and no need to run additional processes.

•	TCP/IP network protocol:  The server workstation network requirements are the same as those for the client workstation.

•	HP VEE:  The server will need a correctly-installed instance of HP VEE version 3.2 or higher.


Reference

Overview

Visual Interface

Properties

Methods

Events

Return Values and Errors

Data Types

Example Session


Properties

Properties are values that control some characteristic of the OCX.  Property values apply to the control as a whole, as opposed to applying only to a single library or function.  Properties are bound to a value of a given OLE Automation type.  Setting the value, and thereby changing the property, is usually accomplished by executing an instruction something like: ControlInstance.Property = value.  Requesting the current property setting requires executing an instruction like: Value=ControlInstance.Property.

HostName

Geometry

Time-out

Debug


Host Name

Description:

This property is a string that selects the workstation you wish to run your remote function.  This may be specified as a human-readable name, such as ‘hplvljfd’, or as an IP address, like ‘15.11.89.118’.  When you change this property value, the OCX will immediately try to connect to an instance of the HP VEE Service Manager running on the requested workstation.

Prototype:

BSTR HostName

Arguments:

An OLE string specifying the host name of the workstation you wish to act as the server for your calls to remote HP VEE User Functions.

Example:

Call1.HostName = "hplvljfd"	' set the HostName property

CurrentHost = Call1.HostName	' get the value of the HostName property

Notes:

•	When an application first loads the OCX, it (the OCX) will attempt to connect to an instance of the HP VEE Service Manager running on the workstation that is running the containing application.


Geometry

Description:

This property specifies the size and placement of the window the server process will map.

Prototype:

BSTR GeometrySpec

Arguments:

An OLE string containing a well-formed geometry specifier that defines the size and placement of the HP VEE server process window.

Example:

Call1.GeometrySpec=”640x480+20+20”

CurrentGeometry=Call1.GeometrySpec

Notes:

This property is a string that takes the general form:

<width><x><height><+|-><x offset><+|-><y offset>

The ‘+’ or ‘-‘ preceding the x an y offsets refer to the window position relative to the screen.  When referencing the y offset, a ‘+’ indicates that the window’s top edge is to be positioned the given number of pixels down from the top edge of the screen.  When ‘-‘, the window’s bottom edge is positioned the given number of pixels up from the bottom of the screen.

When referencing the x offset, a ‘+’ indicates that the window’s left edge is to be positioned the given number of pixels to the right the screen’s left edge.  When ‘-‘, the window’s right edge is positioned the given number of pixels to the left of the screen’s right edge.

For instance, the string ‘640x480+10+20’ maps a window that is 640 pixels wide, 480 pixels high, has its left edge 10 pixels to the right of the screen edge, and has its top edge 20 pixels down from the top edge of the screen.


Time-out

Description:

This property sets the number of seconds to wait for all successive transactions to complete.  If a transaction takes longer than the time-out value to complete, the transaction will return with an error code.

Prototype:

double TimeOut

Arguments:

A double-precision, floating-point value that sets the number of seconds an operation will wait before returning with an error code

Example:

Call1.TimeOut=60

TimeToWait=Call1.TimeOut


Debug

Description:

The state of this property determines the mode (debug or non-debug) an HP VEE User Function will execute in when called from the CallFunction method.

Prototype:

boolean Debug

Arguments:

A boolean value that specifies which mode a User Function should execute in.  A value of 1 indicates that a User Function will execute in debug mode.  A value of 0 indicates that a User Function will execute in non-debug mode.

Example:

Call1.Debug=True

IsInDebugMode=Call1.Debug


Methods

Methods are functions defined in the OCX interface.  Calls to these methods will probably comprise the bulk of any program you write using the OCX.  Each of these functions will return a long word value indicating success or failure.  A return value of 0 indicates success.  A negative return value indicates that the call to a particular function has failed.  An error return value indicates the condition that caused the method call to fail.

LoadVeeLibrary

UnloadVeeLibrary

NumLibraries

NumFunctions

NumArguments

NumReturns

EnumLoadedLibs

EnumFunctions

EnumArguments

EnumReturns

NumActualReturns

EnumReturnTypes

RetrieveFunctionResults

CallFunction

AboutBox


LoadVeeLibrary

Description:

This function causes the OCX to load a library of HP VEE user functions into the server process running on the workstation identified by the Host Name property.  You may load any number of libraries into the OCX concurrently, although the visual interface will show only the last library loaded.

Prototype:

long LoadVeeLibrary(BSTR LibraryPath);

Arguments:

•	LibraryPath:  An OLE string containing the file path of the library of HP VEE User Functions you want to load.

Example:

LibName = "\tmp\random.vee"

result = Call1.LoadVeeLibrary(LibName)

Notes:

•	The path to the library file you select is relative to the file system on the workstation that will execute your HP VEE function.

•	When you specify the path to the library of User Functions, the OCX may change the value to reflect the fully-qualified path to the file.  For instance, if you have a drive letter ‘f:’ that is mapped to a directory on a workstation other than the one running the OCX, specifying ‘f:\my program.vee’ will cause the OCX to substitute the Universal Naming Convention (UNC) equivalent file path.  The result would look something like: ‘\\remoteHost\shareName\directory\my program.vee’.  The OCX does this to precisely identify the correct file in a networked environment.


UnloadVeeLibrary

Description:

This function causes the OCX to remove a library of HP VEE user functions from the server process running on the workstation identified by the Host Name property.  The visual interface will reflect the information about the first library loaded in the session.

Prototype:

long UnloadVeeLibrary(BSTR LibraryPath)

Arguments:

•	LibraryPath:  An OLE string containing the file path of the library of HP VEE User Functions you want to unload.

Example:

LibName = "\tmp\random.vee"

result = Call1.UnloadVeeLibrary(LibName)

Notes:

•	The path to the library file you select is relative to the file system on the workstation that will execute your HP VEE function.


NumLibraries

Description:

This function returns the number of HP VEE User Function libraries the OCX has loaded on the on the workstation identified by the Host Name property..  This function allows you to know how many entries to reserve when you wish to list the libraries the OCX has currently loaded.

Prototype:

long NumLibraries()

Arguments:

None

Example:

Private Sub Call1_LibraryAdded(ByVal NewLibName As String)

    Dim NumLibraries As Long

    Dim LibraryNames()

    NumLibraries = Call1.NumLibraries

    ReDim LibraryNames(NumLibraries)

    For i = 1 To NumLibraries

        LibraryNames(i) = ""

    Next i

    result = Call1.EnumLoadedLibs(LibraryNames)

End Sub

Notes:

You would typically use this function in concert with EnumLoadedLibs.   The most usual case for needing to know this information is when the program user has added a library from the visual interface.  The control is notified of an interactive change of this nature by handling the LibraryAdded event.


NumFunctions

Description:

This function returns the number of  User Functions defined in an HP VEE library file.  This function allows you to know how many entries to reserve when you wish to list the functions contained in a previously-loaded library file.

Prototype:

long NumFunctions(BSTR LibraryPath)

Arguments:

•	LibraryPath:  An OLE string containing the file path of the library of functions you wish to get information about.

Example:

Private Sub Call1_LibraryAdded(ByVal NewLibName As String)

    Dim NumLibraries As Long

    Dim NumFunctions As Long

    Dim FunctionNames()

    Dim LibraryNames()

    NumLibraries = Call1.NumLibraries

    ReDim LibraryNames(NumLibraries)

    For i = 1 To NumLibraries

        LibraryNames(i) = ""

    Next i

    result = Call1.EnumLoadedLibs(LibraryNames)

    For i = 1 To NumLibraries

        NumFunctions = Call1.NumFunctions(LibraryNames(i))

        ReDim FunctionNames(NumFunctions)

        For j = 1 To NumFunctions

            FunctionNames(j) = ""

        Next j

        result = Call1.EnumFunctions(LibraryNames(i), FunctionNames)

    Next i

End Sub

Notes:

You would typically use this function in concert with EunmFunctions.   The most usual case for needing to know this information is when the program user has added a library from the visual interface.  The control is notified of an interactive change of this nature by handling the LibraryAdded event.


NumArguments

Description:

This function returns the number of data input pins on a User Function.  Using this return value, you may allocate storage to hold the names assigned to the input pins.

Prototype:

long NumArguments(BSTR LibraryPath, BSTR FunctionName)

Arguments:

•	LibraryPath:  An OLE string containing the file path for the library which contains the function you are interested in getting information about.

•	FunctionName:  An OLE string that contains the name of the function you are interested in getting information about.

Example:

Private Sub Call1_FunctionSelected(ByVal LibraryPath As String, ByVal FunctionName As String)

    Dim PinNames()

    Dim NumArguments As Long

    NumArguments = Call1.NumArguments(LibraryPath, FunctionName)

    ReDim PinNames(NumArguments)

    For i = 1 To NumArguments

        PinNames(i) = ""

    Next i

    result = Call1.EnumArguments(LibraryPath, FunctionName, PinNames)

End Sub

Notes:

Because many libraries may contain functions of the same name, you must supply the name of the library the function resides in.  This allows the OCX to unambiguously identify the correct function.  This function is usually used in concert with EnumArguments.  The most usual case for using this function is that the program user has highlighted a function from the visual interface.  In this case, the OCX will fire its FunctionSelected event.


NumReturns

Description:

This function returns the number of data output pins on a User Function.  Using this return value, you may allocate storage to hold the names assigned to the output pins.

Prototype:

long NumReturns(BSTR LibraryPath, BSTR FunctionName)

Arguments:

•	LibraryPath:  An OLE string containing the file path for the library which contains the function you are interested in getting information about.

•	FunctionName:  An OLE string that contains the name of the function you are interested in getting information about.

Example:

Private Sub Call1_FunctionSelected(ByVal LibraryPath As String, ByVal FunctionName As String)

    Dim InputPinNames()

    Dim OutputPinNames()

    Dim NumArguments As Long

    Dim NumReturns As Long

    Dim args(3) As Double

    NumArguments = Call1.NumArguments(LibraryPath, FunctionName)

    ReDim InputPinNames(NumArguments)

    For i = 1 To NumArguments

        InputPinNames(i) = ""

    Next i

    result = Call1.EnumArguments(LibraryPath, FunctionName, InputPinNames)

    For i = 1 To 3

        args(i) = i

    Next i

    result = Call1.CallFunction(LibraryPath, FunctionName, args)

    NumReturns = Call1.NumReturns(LibraryPath, FunctionName)

    ReDim OutputPinNames(NumReturns)

    For i = 1 To NumReturns

        OutputPinNames(i) = ""

    Next i

    result = Call1.EnumReturns(LibraryPath, FunctionName, OutputPinNames)

End Sub

Notes:

Because many libraries may contain functions of the same name, you must supply the name of the library the function resides in.  This allows the OCX to unambiguously identify the correct function.  This function is usually used in concert with EnumReturns.  The most usual case for using this function is that the program user has highlighted a function from the visual interface.  In this case, the OCX will fire its FunctionSelected event.


EnumLoadedLibs

Description:

This function will fill an array with the names of the libraries of HP VEE user functions the OCX currently has loaded.

Prototype:

long EnumLoadedLibs(VARIANT LibPathArray)

Arguments:

•	LibPathArray:  An array of variants, where each variant is an OLE string that will be filled with the name of a library of User Functions.

Example:

Private Sub Call1_LibraryAdded(ByVal NewLibName As String)

    Dim NumLibraries As Long

    Dim LibraryNames()

    NumLibraries = Call1.NumLibraries

    ReDim LibraryNames(NumLibraries)

    For i = 1 To NumLibraries

        LibraryNames(i) = ""

    Next i

    result = Call1.EnumLoadedLibs(LibraryNames)

End Sub

Notes:

•	This function is usually used in concert with NumLibraries.  The NumLibraries method is used to reserve enough space to hold the library names.  The most usual case for needing to call this function is when the user has added a library using the visual interface.  To know when this has happened, your program can catch the LibraryAdded event.

•	The return value is the number of library names the OCX was successful in putting into the supplied array.


EnumFunctions

Description:

This function will fill an array with the names of the functions contained in a User Function library.

Prototype:

long EnumFunctions(BSTR LibraryPath, VARIANT FunctionNameArray)

Arguments:

•	LibraryPath:  An OLE string containing the file path to the library of HP VEE User Functions you are interested in getting information about.

•	FunctionNameArrray:  An array of variants, where each variant is an OLE string that will be filled with a User Function name.

Example:

Private Sub Call1_LibraryAdded(ByVal NewLibName As String)

    Dim NumLibraries As Long

    Dim NumFunctions As Long

    Dim FunctionNames()

    Dim LibraryNames()

    NumLibraries = Call1.NumLibraries

    ReDim LibraryNames(NumLibraries)

    For i = 1 To NumLibraries

        LibraryNames(i) = ""

    Next i

    result = Call1.EnumLoadedLibs(LibraryNames)

    For i = 1 To NumLibraries

        NumFunctions = Call1.NumFunctions(LibraryNames(i))

        ReDim FunctionNames(NumFunctions)

        For j = 1 To NumFunctions

            FunctionNames(j) = ""

        Next j

        result = Call1.EnumFunctions(LibraryNames(i), FunctionNames)

    Next i

End Sub

Notes:

•	This function is usually used in concert with the NumFunctions method.  NumFunctions is used to reserve space to hold the array of function names.  The most usual case for needing to call this function is when the user adds a library of User Functions from the visual interface.  To detect this, your program may catch the LibraryAdded event.

•	The return value from this function is the number of entries put into the supplied array.


EnumArguments

Description:

This function will fill an array with the names of the input pins in an HP VEE User Function.

Prototype:

long EnumArguments(BSTR LibraryPath, BSTR FunctionName, VARIANT ArgumentArray)

Arguments:

•	LibraryPath:  An OLE string containing the file path to the library of HP VEE User Functions you are interested in getting information about.

•	FunctionName:  An OLE string containing the name of the function whose data input pins you wish to enumerate.

•	ArgumentArray:  An array of variants, where each variant is an OLE string that will be filled with an input pin name.

Example:

Private Sub Call1_FunctionSelected(ByVal LibraryPath As String, ByVal FunctionName As String)

    Dim PinNames()

    Dim NumArguments As Long

    NumArguments = Call1.NumArguments(LibraryPath, FunctionName)

    ReDim PinNames(NumArguments)

    For i = 1 To NumArguments

        PinNames(i) = ""

    Next i

    result = Call1.EnumArguments(LibraryPath, FunctionName, PinNames)

End Sub

Notes:

•	This function is usually used in concert with the NumArguments method.  NumArguments is used to reserve space to be filled with input pin names.  The most usual case for using this function is when the user selects a function from the visual interface.  To be notified of this, your program may catch the FunctionSelected event.

•	The return value from this function is the number of pin names put into the supplied array.


EnumReturns

Description:

This function will fill an array with the names of output pins in an HP VEE User Function.

Prototype:

long EnumReturns(BSTR LibraryPath, BSTR FunctionName, VARIANT ReturnArray)

Arguments:

•	LibraryPath:  An OLE string containing the file path to the library of HP VEE User Functions you are interested in getting information about.

•	FunctionName:  An OLE string containing the name of the function whose data input pins you wish to enumerate.

•	ReturnArray:  An array of variants, where each variant is an OLE string that will be filled with an output pin name.

Example:

Private Sub Call1_FunctionSelected(ByVal LibraryPath As String, ByVal FunctionName As String)

    Dim InputPinNames()

    Dim OutputPinNames()

    Dim NumArguments As Long

    Dim NumReturns As Long

    Dim args(3) As Double

    NumArguments = Call1.NumArguments(LibraryPath, FunctionName)

    ReDim InputPinNames(NumArguments)

    For i = 1 To NumArguments

        InputPinNames(i) = ""

    Next i

    result = Call1.EnumArguments(LibraryPath, FunctionName, InputPinNames)

    For i = 1 To 3

        args(i) = i

    Next i

    result = Call1.CallFunction(LibraryPath, FunctionName, args)

    NumReturns = Call1.NumReturns(LibraryPath, FunctionName)

    ReDim OutputPinNames(NumReturns)

    For i = 1 To NumReturns

        OutputPinNames(i) = ""

    Next i

    result = Call1.EnumReturns(LibraryPath, FunctionName, OutputPinNames)

End Sub

Notes:

•	This function is usually used in concert with the NumReturns method.  NumReturns is used to reserve space to be filled with data output pin names.  The most usual case for needing to use this function is when the program user has selected a function using the visual interface.  To be notified of this, your program may catch the FunctionSelected event.

•	The call to this function must follow a call to CallFunction, where the HP VEE User Function is the same as the function you want to get information about.  This is necessary because an HP VEE function may fire some, none, or all of its data out pins.  In addition, the type of data propagating from a data out pin is not known until after the function runs.

•	The return value from this function is the number of data output names put into the supplied array.


NumActualReturns

Description:

This function returns the number of results that a call to an HP VEE User Function propagated.

Prototype:

long NumActualReturns(BSTR LibraryPath, BSTR FunctionName)

Arguments:

•	LibrayPath:  An OLE string containing the file path to the HP VEE library that houses the User Function of interest.

•	FunctionName:  An OLE string containing the name of the function whose results you are interested in.

Example:

Private Sub Command1_Click()

    Dim args(2)

    Dim resultTypes() As Integer

    Dim resultSize() As Integer

    Dim nactualResults As Integer

    Dim libName As String

    Dim funcName As String

    libName = "\tmp\uf1.vee"

    funcName = "uf1"

    args(1) = 100

    args(2) = 200

    result = Call1.LoadVeeLibrary(libName)

    result = Call1.CallFunction(libName, funcName, args)

    nactualResults = Call1.NumActualReturns(libName, funcName)

    ReDim resultTypes(nactualResults)

    ReDim resultSize(nactualResults)

    If nactualResults > 0 Then

        lower = LBound(resultTypes)

        upper = UBound(resultTypes)

        For i = lower To upper

            resultTypes(i) = i

        Next i

        result = Call1.EnumReturnTypes(libName, funcName, resultTypes, resultSize)

    End If

End Sub

Notes:

•	This function is usually used in concert with the EnumReturnTypes and RetrieveFunctionResults methods.  You would use this function to reserve space to be filled in with the data type and shape for each output pin that actually created a result.

•	HP VEE User Functions may propagate some, none, or all of their data output pins.  In addition, the type and shape of propagated data may change from one execution run to the next.  It is this characteristic of User Functions that makes this method necessary.

•	The most usual use of this method is following a call to CallFunction and preceding a call to RetrieveFunctionResults.


EnumReturnTypes

Description:

This function fills in two arrays with information about the return values from an HP VEE User Function.  There is one array for the data type information and the other holds the data shape information.  Each array has as many elements as there are actual results from the last execution of the associated User Function.

Prototype:

long EnumReturnTypes(BSTR LibraryPath, BSTR FunctionName, VARIANT TypeArray, VARIANT ElementCountArray)

Arguments:

•	LibraryPath:  An OLE string containing the file path to the User Function you have previously executed.

•	FunctionName:  An OLE string containing the name of the function you have previously executed.

•	TypeArray:  An array of variants, where each element of the array will hold another array of one of the fundamental types.  The encapsulated array will be filled in with the data type information for the corresponding data out pin.

•	ElementCountArray: An array of variants, where each element of the array will hold another array of one of the fundamental types.  The encapsulated array will be filled in with the data shape information for the corresponding data out pin.

Example:

The following two illustrations depict the program we will write to exercise the EnumReturnTypes method.  We have a simple HP VEE User Function that takes two arguments, turns them into integers, and swaps their positions relative to the data input pin positions.

Figure 8: Our Example HP VEE User Function

Figure 9: Our Finished Form

Private Sub Command1_Click()

    Dim args(2)

    Dim firstArg As Integer

    Dim secondArg As Integer

    Dim ResultTypes() As Long

    Dim ResultCount() As Long

    Dim FunctionResults()

    LibName = "\vee\cur32\src\ocx\call\Hlp\swap.vee"

    FunctionName = "swap"

    result = Call1.LoadVeeLibrary(LibName)

    firstArg = 4

    secondArg = 6

    args(1) = firstArg

    args(2) = secondArg

    result = Call1.CallFunction(LibName, FunctionName, args)

    NumResults = Call1.NumActualReturns(LibName, FunctionName)

    ReDim ResultTypes(NumResults)

    ReDim ResultCount(NumResults)

    result = Call1.EnumReturnTypes(LibName, FunctionName, ResultTypes, ResultCount)

    ReDim FunctionResults(NumResults)

    lower = LBound(ResultTypes)

    upper = UBound(ResultTypes)

    For i = lower To upper

        Select Case ResultTypes(i)

            Case 2                                  ' short

                Dim shortResult() As Integer

                ReDim shortResult(ResultCount(i))

                FunctionResults(i) = shortResult

            Case 3                                  ' long

                Dim longResult() As Long

                ReDim longResult(ResultCount(i))

                FunctionResults(i) = longResult

            Case 4                                  ' float

                Dim floatResult() As Single

                ReDim floatResult(ResultCount(i))

                FunctionResults(i) = floatResult

            Case 5                                  ' double

                Dim doubleResult() As Double

                ReDim doubleResult(ResultCount(i))

                FunctionResults(i) = doubleResult

            Case 8                                  ' string

                Dim stringResult() As String

                ReDim stringResult(ResultCount(i))

                FunctionResults(i) = stringResult

            Case Else                               ' hmmm.

        End Select

    Next i

    result = Call1.RetrieveFunctionResults(LibName, FunctionName, FunctionResults)

    For i = lower To upper

        variantType = VarType(FunctionResults(i)) And Not 8192  ' get the fundamental data type

        Select Case variantType

            Case 2

            Case 3

                If IsArray(FunctionResults(i)) Then

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    Else

                        Text2.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    End If

                Else

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)

                    Else

                        Text2.Text = FunctionResults(i)

                    End If

                End If

            Case 4

            Case 5

            Case 8

            Case Else

        End Select

    Next i

End Sub

Notes:

This function returns as many entries as there were output pins that actually fired.  The returned information does not specify which pins fired, however.  If the User Function has three output pins, and pins one and three fired, this function would return an array two elements long.


RetrieveFunctionResults

Description:

This function will return the results of the latest call to a User Function.  You would normally use this function immediately after making a call to the CallFunction method.

Prototype:

long RetrieveFunctionResults(BSTR LibraryPath, BSTR FunctionName, VARIANT ResultArray)

Arguments:

•	LibraryPath:  An OLE string containing the file path of the library of HP VEE User Functions which houses the function of interest.

•	FunctionName:  An OLE string containing the name of the function whose results you wish to retrieve.

•	ResultArray:  An array of variants having as many elements as there are output pins that have fired.  Each element in the array will hold another array of a fundamental data type that holds the data returned on each output pin.

Example:

The following two illustrations depict the program we will write to exercise the RetrieveFunctionResults method.  We have a simple HP VEE User Function that takes two arguments, turns them into integers, and swaps their positions relative to the data input pin positions.

Figure 10: Our Example HP VEE User Function

Figure 11: Our Finished Form

Private Sub Command1_Click()

    Dim args(2)

    Dim firstArg As Integer

    Dim secondArg As Integer

    Dim ResultTypes() As Long

    Dim ResultCount() As Long

    Dim FunctionResults()

    LibName = "\vee\cur32\src\ocx\call\Hlp\swap.vee"

    FunctionName = "swap"

    result = Call1.LoadVeeLibrary(LibName)

    firstArg = 4

    secondArg = 6

    args(1) = firstArg

    args(2) = secondArg

    result = Call1.CallFunction(LibName, FunctionName, args)

    NumResults = Call1.NumActualReturns(LibName, FunctionName)

    ReDim ResultTypes(NumResults)

    ReDim ResultCount(NumResults)

    result = Call1.EnumReturnTypes(LibName, FunctionName, ResultTypes, ResultCount)

    ReDim FunctionResults(NumResults)

    lower = LBound(ResultTypes)

    upper = UBound(ResultTypes)

    For i = lower To upper

        Select Case ResultTypes(i)

            Case 2                                  ' short

                Dim shortResult() As Integer

                ReDim shortResult(ResultCount(i))

                FunctionResults(i) = shortResult

            Case 3                                  ' long

                Dim longResult() As Long

                ReDim longResult(ResultCount(i))

                FunctionResults(i) = longResult

            Case 4                                  ' float

                Dim floatResult() As Single

                ReDim floatResult(ResultCount(i))

                FunctionResults(i) = floatResult

            Case 5                                  ' double

                Dim doubleResult() As Double

                ReDim doubleResult(ResultCount(i))

                FunctionResults(i) = doubleResult

            Case 8                                  ' string

                Dim stringResult() As String

                ReDim stringResult(ResultCount(i))

                FunctionResults(i) = stringResult

            Case Else                               ' hmmm.

        End Select

    Next i

    result = Call1.RetrieveFunctionResults(LibName, FunctionName, FunctionResults)

    For i = lower To upper

        variantType = VarType(FunctionResults(i)) And Not 8192  ' get the fundamental data type

        Select Case variantType

            Case 2

            Case 3

                If IsArray(FunctionResults(i)) Then

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    Else

                        Text2.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    End If

                Else

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)

                    Else

                        Text2.Text = FunctionResults(i)

                    End If

                End If

            Case 4

            Case 5

            Case 8

            Case Else

        End Select

    Next i

End Sub

Notes:

The process of calling a remote function is separate from retrieving the function results because the number of data output pins that a User Function will fire, and the type of data each pin propagates, is not known until the User Function actually runs.  In order to build the data space to hold the return values, those values’ types and shapes must be defined.


CallFunction

Description:

This method is the one that invokes an HP VEE User Function, passing arguments from your program to the User Function’s data input pins.

Prototype:

long CallFunction(BSTR LibraryPath, BSTR FunctionName, [optional] VARIANT Arguments)

Arguments:

•	LibraryPath:  An OLE string containing the file path of the library of HP VEE User Functions which houses the function of interest.

•	FunctionName:  An OLE string containing the name of the function you wish to invoke.

•	Arguments:  This is an optional parameter.  If present, this is an array of variants, where each element in the array holds data for one User Function input pin.  The lowest-indexed value in the variant array is delivered to the top-most data pin.  The highest-indexed value in the variant array is delivered to the bottom-most input pin.

Example:

The following two illustrations depict the program we will write to exercise the CallFunction method.  We have a simple HP VEE User Function that takes two arguments, turns them into integers, and swaps their positions relative to the data input pin positions.

Figure 12: Our Example HP VEE User Function

Figure 13: Our Finished Form

Private Sub Command1_Click()

    Dim args(2)

    Dim firstArg As Integer

    Dim secondArg As Integer

    Dim ResultTypes() As Long

    Dim ResultCount() As Long

    Dim FunctionResults()

    LibName = "\vee\cur32\src\ocx\call\Hlp\swap.vee"

    FunctionName = "swap"

    result = Call1.LoadVeeLibrary(LibName)

    firstArg = 4

    secondArg = 6

    args(1) = firstArg

    args(2) = secondArg

    result = Call1.CallFunction(LibName, FunctionName, args)

    NumResults = Call1.NumActualReturns(LibName, FunctionName)

    ReDim ResultTypes(NumResults)

    ReDim ResultCount(NumResults)

    result = Call1.EnumReturnTypes(LibName, FunctionName, ResultTypes, ResultCount)

    ReDim FunctionResults(NumResults)

    lower = LBound(ResultTypes)

    upper = UBound(ResultTypes)

    For i = lower To upper

        Select Case ResultTypes(i)

            Case 2                                  ' short

                Dim shortResult() As Integer

                ReDim shortResult(ResultCount(i))

                FunctionResults(i) = shortResult

            Case 3                                  ' long

                Dim longResult() As Long

                ReDim longResult(ResultCount(i))

                FunctionResults(i) = longResult

            Case 4                                  ' float

                Dim floatResult() As Single

                ReDim floatResult(ResultCount(i))

                FunctionResults(i) = floatResult

            Case 5                                  ' double

                Dim doubleResult() As Double

                ReDim doubleResult(ResultCount(i))

                FunctionResults(i) = doubleResult

            Case 8                                  ' string

                Dim stringResult() As String

                ReDim stringResult(ResultCount(i))

                FunctionResults(i) = stringResult

            Case Else                               ' hmmm.

        End Select

    Next i

    result = Call1.RetrieveFunctionResults(LibName, FunctionName, FunctionResults)

    For i = lower To upper

        variantType = VarType(FunctionResults(i)) And Not 8192  ' get the fundamental data type

        Select Case variantType

            Case 2

            Case 3

                If IsArray(FunctionResults(i)) Then

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    Else

                        Text2.Text = FunctionResults(i)(LBound(FunctionResults(i)))

                    End If

                Else

                    If i = 1 Then

                        Text1.Text = FunctionResults(i)

                    Else

                        Text2.Text = FunctionResults(i)

                    End If

                End If

            Case 4

            Case 5

            Case 8

            Case Else

        End Select

    Next i

End Sub

Notes:

•	It is not necessary to supply any arguments to a User Function.  If you do not supply arguments, the OCX will manufacture default values of the correct type and shape for each of the User Function input pins.

•	You may supply more or fewer arguments than the User Function has input pins.  The OCX will provide default values for input pins that have no corresponding program-supplied values.  For the case where there are more program-supplied arguments than there are data input pins, the OCX will ignore the extra parameters.


AboutBox

Description:

This function causes the OCX to display its copyright dialog.

Prototype:

void AboutBox()

Arguments:

None.

Example:

Call1.AboutBox


Events

Events permit the OCX to notify its containing application that something of significance has happened.  The OCX will fire events to its container when the user changes values using the visual interface, and when it detects an error in the HP VEE server process.

Most container applications will provide a mechanism, usually through the use of a callback function, to allow the program to respond to the events an OCX fires.

Host Name Changed

Library Added

Geometry Changed

Debug Changed

Function Selected

RPC Error


Host Name Changed

Description:

The OCX fires this event when the user enters a new host name into the visual interface’s “Host Name:” edit field.

Prototype:

void HostNameChanged(BSTR NewHostName)

Arguments:

NewHostName:  An OLE string containing the contents of the edited “Host Name:” control.

Example:

Private Sub Call1_HostNameChanged(ByVal NewHostName As String)

    NewHost = NewHostName   ' NewHost is a global

End Sub


Library Added

Description:

The OCX will fire this event when the user adds a library of HP VEE User Functions by clicking the “Browse…” button or by editing the “File Path:” control on the visual interface.

Prototype:

void LibraryAdded(BSTR NewLibName)

Arguments:

NewLibName:  An OLE string containing the contents of the “File Path:” edit control on the visual interface.

Example:

Private Sub Call1_LibraryAdded(ByVal NewLibName As String)

    Dim NumLibraries As Long

    Dim LibraryNames()

    NumLibraries = Call1.NumLibraries

    ReDim LibraryNames(NumLibraries)

    For i = 1 To NumLibraries

        LibraryNames(i) = ""

    Next i

    result = Call1.EnumLoadedLibs(LibraryNames)

End Sub

Notes:

You can get a listing of all currently-loaded libraries by using a call to EnumLoadedLibs.


Geometry Changed

Description:

The OCX will fire this event when the user edits the “Geometry:” control on the visual interface.

Prototype:

void GeometryChanged(BSTR NewGeometry)

Arguments:

NewGeometry:  An OLE string containing the contents of the “Geometry:” control on the visual interface.

Example:

Private Sub Call1_GeometryChanged(ByVal NewGeometry As String)

    NewGeomString = NewGeometry      ' NewGeomString is a global

End Sub


Debug Changed

Description:

The OCX will fire this event when the user changes the state of the “Debug:” check box on the visual interface.

Prototype:

void DebugChanged(boolean NewDebugState)

Arguments:

NewDebugState:  A Boolean value that reflects the state of the “Debug:” check box on the visual interface.  This value will be true when the box is checked and false when the box is cleared.

Example:

Private Sub Call1_DebugChanged(ByVal NewDebugState As Boolean)

    debugState = NewDebugState      ' debugState is a global

End Sub


Function Selected

Description:

The OCX will fire this event when the user selects one of the functions in the “Functions:” list box on the visual interface.

Prototype:

void FunctionSelected(BSTR LibraryPath, BSTR FunctionName)

Arguments:

•	LibraryPath:  An OLE string containing the file path to the library of User Functions which houses the displayed User Functions.

•	FunctionName:  An OLE string containing the name of the User Function the user selected

Example:

Private Sub Call1_FunctionSelected(ByVal LibraryPath As String, ByVal FunctionName As String)

    Dim PinNames()

    Dim NumArguments As Long

    NumArguments = Call1.NumArguments(LibraryPath, FunctionName)

    ReDim PinNames(NumArguments)

    For i = 1 To NumArguments

        PinNames(i) = ""

    Next i

    result = Call1.EnumArguments(LibraryPath, FunctionName, PinNames)

End Sub

Notes:

To get information about the newly-selected User Function , you can call the EnumArguments method.


RPC Error

Description:

The OCX will fire this event when it detects that the associated HP VEE server process has thrown an error.

Prototype:

void RPCError(short ErrorNumber, BSTR ErrorString)

Arguments:

•	ErrorNumber:  A short integer containing the HP VEE error number that cased the OCX to generate this event.

•	ErrorString:  An OLE string containing the text of the HP VEE error that would normally be displayed in an HP VEE error message dialog.

Example:

Private Sub Call1_RPCError(ByVal ErrorNumber As Integer, ByVal ErrorString As String)

    ' process the error

End Sub


Error Numbers

-1	Load library failed.
-2	Unload library failed.
-3	An attempt to connect to the HP VEE Service Manager on a given host has failed.
-4	An attempt to disconnect from the HP VEE Service Manager on a given host has failed.
-5	An attempt to load a library of HP VEE User Functions has failed, because there is no Service Manager running on a given host, or the Service Manager has exited.
-6	Trying to retrieve information about a library of VEE User Functions that doesn’t exist.
-7	An error occurred trying to free the information about an HP VEE User Function .
-8	An error occurred while getting information about an HP VEE User Function.
-9	An error occurred while trying to read the function names form a library.
-10	An error occurred while trying to free the function names in a library.
-11	Couldn’t find the requested User Function in a library.
-12	The named library is not loaded into the OCX.
-13	The named function does not exist in the library.
-14	The argument(s) supplied in the CallFunction method are invalid for that HP VEE User Function.
-15	The argument(s) supplied in the CallFunction method cannot be converted to the type needed to satisfy the User Function.
-16	The value given as an argument to RetrieveFunctionResults cannot be the target for the value the User Function returned.
-17	The results of a call to a User Function cannot be returned in a call to RetriveFunctionResults.


Data Types

The OCX supports long and short integers, single and double-precision floating-point numbers, OLE strings, and singly-dimensioned arrays of all the aforementioned as arguments to and return values from User Functions.

The composite data types are represented as follows:

HP VEE Data Type	OLE Data Representation
Coord	A singly-dimensioned array of double-precision, floating-point numbers.  The array has as many elements as there are fields in the coordinate.  A coordinate array is a linear array, where each coordinate value directly adjoins other coordinate values.
Complex	A singly-dimensioned array of two double-precision, floating-point numbers.  The first element represents the real part; the second element represents the imaginary part.  A complex array is a  linear array, where each complex value directly adjoins other complex values.
PComplex	A singly-dimensioned array of two double-precision, floating-point numbers.  The first element represents the magnitude; the second element represents the phase.  A complex array is a  linear array, where each polar complex value directly adjoins other polar complex values
Waveform	A singly-dimensioned array of double-precision, floating-point numbers.
Spectrum	A singly-dimensioned array of  polar complex values.


Manually Configuring the OCX

If you wish to copy the OCX onto a Windows 95(tm) or Windows NT(tm) workstation that does not contain an installation of HP VEE, you will need to configure the workstation to use the OCX.  Configuration consists of copying the necessary files, adding file path registry entries, and registering the OCX.

You will need to ensure that the following files are present and exist in a directory (or directories) listed in your “Path” environment variable.  All of the files are distributed with the HP VEE installation and are redistributable.  By convention, all of these files normally reside in your system directory.

•	call.ocx:  The OCX implementation file.

•	libvapi.dll:  A library that implements the C to VEE RPC client capabilities.

•	MFC42.DLL:  Microsoft Foundation Class(tm) library.

•	MSVCRT.DLL:  A shared version of  the C run-time library.

•	call.hlp:  This help file.

For the OCX to find its help file when you click the help button on either the OCX visual interface or the properties dialog, you will need to add a registry entry telling the OCX where its support files are.  The registry entry key you need to create is:

HKEY_LOCAL_MACHINE\SOFTWARE\Hewlett-Packard\VEE\4.0

Under this key, you need to create a registry string value named “BaseDir”.  Set this registry value’s data to file path into which you copied the help file.  The following is an illustration showing the registry editor with the entries we just discussed.

Figure 14: Required Registry Entries

Once you have copied the files, you need to configure the OCX for use by asking it to set the appropriate registry entries.  There are two ways to do this.  The first way is to use a utility that comes with many software development environments.  The utility is named “regsvr32”.  If you have this utility, you can register the OCX from a command console by:

•	changing to the directory that contains the OCX.

•	executing the command “regsvr32 -c call.ocx”

You will see a message box appear that informs you of the results of configuring the OCX.  The most likely cause of failing to completely register the OCX is that one of the libraries listed above can’t be found in your path.

If you don not have regsvr32, you may still register the OCX by writing a simple C program.


Registering the OCX Without regsvr32

If your system does not have the regsvr32 utility, you may register the OCX using a C program.  You will need a C development environment.  The following is a program you can compile to register the OCX:

/*********************************************************************

File: RegOcx.c

Description: An example program to register the Callable VEE OCX

Revision: 1.1

Date: 97/02/04 13:43:14

Copyright: 1997 Hewlett-Packard Company.  All rights reserved.

*********************************************************************/

#include <windows.h>

#include <tchar.h>

#include <stdio.h>

int main(int argc, char *argv[]){

int returnVal=0;

HINSTANCE ocxInstance;

FARPROC registerFunction;

ocxInstance=LoadLibraryEx(_T("call.ocx"), NULL /* reserved */,

  0 /* flags */);

if(!ocxInstance){

printf("Failure tyring to load ocx.  Error Number: %ld\n",

   GetLastError());

return -1;

}

registerFunction=GetProcAddress(ocxInstance, _T("DllRegisterServer"));

if(!registerFunction){

printf("Failure tyring to find registry function.  Error Number: %ld\n",

   GetLastError());

FreeLibrary(ocxInstance);

return -2;

}

registerFunction();

FreeLibrary(ocxInstance);

return returnVal;

}

To compile this program with a Microsoft(tm) C development environment, type these commands into a command console:

•	cl -c -Od -Zi -W3 -DWIN32 RegOcx.c

•	link -debug -out:RegOcx.exe -subsystem: console RegOcx.obj libc.lib

Then, to register the OCX, do the following from a command console:

•	Change directories to the directory that contains the OCX.

•	Execute RegOcx.exe


Glossary

Library

A library is an HP VEE program file that contains User Function definitions.  This is a normal program file in every way, in that the library may contain a complete program in addition to the User Function definitions.  The OCX allows you to execute the functions contained in the library, but does not allow you to run a program as a whole.

Service Manager

Any workstation you wish to be a server for remote function requests needs to have a process running to handle the initial incoming connections.  This process is a program you run on Windows NT(tm) and Windows 95(tm).  It is called “veesm.exe” and is found in the HP VEE installation directory.  You must run this program for the workstation to act as a server.  Typically, you would want to create an icon for to run this program from you program manager’s “Startup” folder.

On HP-UX, the installation procedure makes the appropriate entries in files that govern the inet daemon’s behavior.  Because the inet daemon is configured to appropriately route HP VEE remote function call, it is not necessary to run additional processes; the inet daemon creates a service manager process transparently.

Data Shape

Data shape refers to the number of elements in any given argument to or result from an HP VEE User Function.  The only shapes currently supported are scalar values (the number of elements in any one value is one) and singly-dimensioned arrays (the number of elements in any one value is greater than one).  It should be noted that the composite data types, like coordinates and complex numbers, are represented as singly-dimensioned arrays of double-precision, floating-point values.


Overview

The OCX is intended to allow component-aware applications to execute HP VEE functions remotely.  To use the OCX, you need to embed it in an application that is capable of acting as an a control container (or that is capable of participating in an OLE Automation conversation, if you don’t need the visual interface).   The “remote” part of this refers to the fact that the “C to VEE RPC” mechanism, upon which the OCX is built, is a network-enabled library.

When you first direct the OCX to connect to a particular service workstation, the library from which the OCX derives contacts the service manager running on that host.  The service manager will then create an instance of an HP VEE environment that is set up specifically to deal with requests to execute remote functions.  The service manager then establishes a link between the HP VEE server process and the OCX and drops out of the loop.  Further communication is a direct connection between the OCX and the HP VEE server process.

Once you have established a connection to the desired host workstation, you will want to load a library of HP VEE “User Functions”.  It is important to note that the path to the HP VEE library is relative to the server workstation.  Let’s say that the workstation running the application which hosts the OCX is called “client” and that the workstation running the HP VEE server process is called “server”.  Let’s further say that you have told the OCX to load a library identified by the path “d:\my prog.vee”.  The drive and path refer to a file located on the workstation called “server”.  That said, there is nothing to prevent the OCX from running on the same workstation as the application hosting the OCX.

Once you have loaded a library, you may examine information about and call the functions in the library.  An example session illustrates these steps.