An Architecture for Virtual Systems

John Dumais

Hewlett-Packard, Measurement Systems Division

815 14th Street, SW

Loveland, CO 80537

Instrument-control systems are increasingly using more than one application and/or language to supply all the services expected of them. One single tool doesn't necessarily provide everything needed to manage parallel, concurrent instrument control, database access, etc. Ideally, we (those of us involved in system integration) want to have the freedom to choose the tool best suited for a particular part of the task at hand. In the past, integrating pieces of a system into a cohesive whole has been a largely ad-hoc and labor-intensive proposition. We wanted to provide an architecture that makes it easy to build a sophisticated integrated system.

We would like for whatever solution we come up with to be easily integrated into a system composed of many individual pieces; each of which provides a tool useful for a given task. You can view such an architecture as a sort of `Virtual System'; where the systemic functionality derives from the coordination of individual pieces. The problem then boils down to defining an architecture that allows us to expose its usefulness as a tool while providing a mechanism to communicate with other useful tools. With this architecture, we can build an entire system from individual components, and have the system look and function like a single entity.

With the latest version of Hewlett-Packard's Visual Engineering Environment (HP VEE), we think we may have the first stab at implementing the virtual system. HP VEE has followed an evolutionary path, leading in stages toward its role as a component in increasingly capable and sophisticated systems.

VEE to VEE RPC's

Earlier HP VEE features laid a foundation that addressed part of this problem. The `VEE RPC' mechanism allows an HP VEE program to execute HP VEE functions on a remote workstation1. These calls to remote functions look exactly like calls to functions defined locally within your program. Data from the local program is marshaled to the remote function, which marshals resultant data back to the client program. This provides the capability to easily build a distributed instrument-control application2.

The `Callable' VEE Library

What we refer to as the `Callable' VEE library extends the VEE RPC mechanism. It exposes the ability to call a remote HP VEE function from a client program written in C or C++. The `Callable' VEE library is implemented as a set of header files, defining data structures and function prototypes, and a library that carries out the actions defined in the API.

How is All This Relevant?

The next logical progression in this sequence is the subject of the remainder of this article: the `Callable' VEE Custom Control. We'll discuss the thought process that led us to choose to implement the `Callable' VEE Control as we did and describe the control's use in an integrated system.

What A Good Solution Should Provide

In trying to define the architecture within which `Callable' VEE would participate, we first tried to enumerate the characteristics of a `good' architecture. We came up with the following list:
We wanted to be able to interoperate with as many other languages and applications as we reasonably could. In addition, we wanted to expose our services to the rest of a system without the other systemic components needing to make arrangements that could be applied only to `Callable' VEE. The fact that `Callable' VEE is inherently a networked environment shouldn't necessitate a change in the way you are used to gaining network access on a given system. We wanted to provide the facility to easily identify HP VEE functions accessible from your workstation. We wanted an architecture that would appeal to the widest potential customer base. Our last criterion was that the architecture should be one that customers can adopt with a minimum of fuss.

The Solution

An architecture that meets all these requirements already exists in the form of Custom Controls. These have been known previously as OLE Controls, and the latest terminology identifies them as Active Controls or ActiveX components. Any language that can act as a control container or that can participate in an OLE Automation conversation should be able to make use of the services we provide. The roster of scripting languages, applications, and programming environments that allow the system integrator to build an OLE-Automation-enabled application is growing rapidly.

Custom controls are built upon a technology known as the Component Object Model (COM). COM has a number of characteristics that make it uniquely capable of aiding us in solving the problem we were faced with.

Technology Foundations

Let's take a look at some of the technology that makes interoperability through custom controls possible. Custom controls employ specific uses of a broader technology known as Object Linking and Embedding (OLE). OLE, in turn, uses the mechanism supplied by another underlying technology known as the Component Object Model (COM). OLE is becoming an anachronistic term, reflecting the original use of this technology to embed documents from one type of application into a document of a second type of application. OLE is probably more appropriately thought of as a technology to integrate independent functionality into a cohesive application.

COM

COM is the term used to describe the technology that allows systemic objects to find out about and use the services of other objects. An `object', in its most general sense, is a piece of software that can supply some service and can tell you what services it can provide. Along with the individual service-providing components, or objects, COM supplies a means by which an object may establish communication with other components.

COM enables software reuse at the binary (as opposed to source code) level. COM is the mechanism through which binary objects expose their services and make connection to other objects' services. COM doesn't specify what services an object exposes, just how it exposes them.

A COM object implements its services by grouping functions related to each service into `interfaces'. An object typically implements as many interfaces as it has services it wants to provide. Each object must supply, as a bare minimum, an interface known as `IUnknown'. This interface contains a function that allows you to find out about the other interfaces, or services, an object provides. This function is `QueryInterface'.

An interface is immutable. This implies a contract between a service provider and a service consumer. Once defined, an interface can never be changed, either in the specific functions it provides or in the tasks that it performs. This allows you to construct a client, secure in the knowledge that you will always have access to the same signature and functionality

OLE Automation

Where COM provides the mechanism for objects to cooperate, OLE specifies the protocols necessary for cooperating objects to make use of `well known' capabilities. These protocols identify the specific interfaces, and the specific functions within each interface, necessary for one object to ask another to do something.

A technology known as OLE Automation defines a protocol for a client to discover and make use of the capabilities a server exposes. OLE Automation makes it possible for a client to call the functions in a server; sending the server any data necessary for it (the server) to complete its tasks and receiving any results.

Because OLE Automation has a defined protocol for discovering the functions a server exposes and for sending and receiving data, any OLE Automation-aware client should be able to use the services in an automation-enabled server.

Custom Controls

Custom Controls build on OLE Automation to define a communications protocol between an embedding application and the control itself. Custom Controls introduce three concepts central to the coordination between the control and its containing application:
Properties define some characteristic of the control, such as its title, background color, or the name of a host workstation on which it is to perform its tasks. Part of the Custom Control protocol defines the mechanism by which a containing application can set and query a control's properties.

Events are an asynchronous means for the control to alert its containing application that something significant has happened. For instance, if the control allows its properties to be changed through the use of a visual interface, it would fire an event to alert its container that one of its properties has been interactively changed.

You tell a control that you want it to execute one if its functions by invoking a method. A control's methods define the set of actions it is capable of performing. OLE Automation provide a protocol whereby a client application can discover the methods a control exposes.

The `Callable' VEE Library

The `Callable' VEE C interface is a set of functions that allow you to:
If we were to expose these capabilities in an automation-enabled server, automation-aware clients of most any form could integrate HP VEE functions into their environment in an industry-standard way. This is precisely what the `Callable' VEE custom control does.

The `Callable' VEE Custom Control

One of HP VEE's real strengths is its ability to easily control test instrumentation. If you have components that allow you to easily perform the other tasks required of you application, using the `Callable' VEE custom control to perform the instrument-control portion would then give you an entirely integrated system. The combination of easy instrument control and the ability to make the instrument control available as a systemic component is tremendously powerful.

Let's Take a Look

The Visual Interface

Figure 1: A Visual Basic Form with the Callable VEE OCX

Figure 1 is a Visual Basic form containing an instance of the `Callable' VEE custom control and a command button (labeled `Execute Function'). Pressing the button causes the Basic program to call the HP VEE function `random'.

The user has a great deal of flexibility when using the control's visual interface. The `Browse' button allows the user to select a library of HP VEE functions by presenting the standard `Open File' dialog. The control has the ability to browse and load libraries on any computer on the network. The user may also select a host computer which will run the functions in the selected library.

Once the user has selected a library, the visual interface allows the user to view all of the information relevant to the functions the HP VEE library contains. Especially important is the ability to display the function's description text. This is the equivalent of a comment field and generally explains what the function does.

Additional fields on the control allow the user to specify the HP VEE window placement and the mode to use when executing the functions. When you execute HP VEE functions, they may pop up panels3. The `Geometry' field allows the user to precisely control the size and location of HP VEE function panels. In addition, the `Debug' check box allows a developer to run the HP VEE function in a mode that allows for debugging on both the client and server ends.

An Example Session

Let's look at what it takes to call an HP VEE function using the `Callable' VEE control. For this example session, we'll construct a Visual Basic program that uses our control and a button you can push to make the Basic program execute an HP VEE function.

To insert an instance of the `Callable' VEE control into a form, you select from a list of insertable objects. Figure 2 illustrates this.

Figure 2: Inserting the Control Into a Form

We will also add a `Command Button' to this form. Clicking the button causes Basic to invoke the button's click handler function. That Basic function loads a library of HP VEE functions, then calls one of the HP VEE functions. It is shown in Listing 1.

Listing 1: Calling an HP VEE Function
Private Sub Command1_Click()
    libraryName = "\tmp\random.vee"
    functionName = "random"
    Dim args(2)
    Dim returnVals(1)
    Dim randomReturn(1) As Double

    args(1) = 10 ' high limit for random number
    args(2) = 0 ' low limit for random number

    result = Call1.LoadVeeLibrary(libraryName)
    result = Call1.CallFunction(libraryName, functionName, args)

    returnVals(1) = randomReturn

    result = Call1.RetrieveFunctionResults(libraryName, functionName, returnVals)
End Sub

The name given the instance of our control is `Call1'.4 To get information from the control, or to ask it to do something, you use the control name, followed by a `dot', followed by the command you wish to invoke. In this case, we load a library of HP VEE functions. We then call one of the functions, passing two arguments to it.

One of the design features of the `Callable' VEE control is its ability to adapt the arguments you supply a function to the arguments the function originally defined. If you look at Figure 3, you'll see that our `random' function takes two arguments of type `any'5. HP VEE is a type-less system, so you normally don't need to concern yourself with the exact data representation a function uses. We carried this capability forward into the control and took it a step further. You can pass any Basic data type to a function, and the control will coerce it into the type the function defines. In addition, you need not pass the same number of arguments that the function defines. This is in keeping with the credo of OLE Automation. In essence that credo can be stated as:

Ya know dude, like I want to call the Bob method, and, like, I have some `stuff' for it.

It is the control's responsibility to ensure that the function calls will succeed if at all possible.

Figure 3: The 'random' Function

The next illustrations show our Basic program and HP VEE function executing in concert. Figure 4 is the `random' function's panel view as it appears when called with our control's `Debug' option is not selected. Figure 5 shows depicts the result when we run our function in debug mode. Figure 6 shows the Basic program's debug window after capturing the `random' function's return value.

Figure 4: The 'random' Function Panel View

Figure 5: The 'random' Function in 'Debug' Mode

Figure 6: The 'random' Function's Return Value

Summary

So, there you have it. We're on the brink of making good on the promises that component-aware systems have made. By taking advantage of evolving technologies, component-aware software is making it possible to easily integrate `Virtual Systems' composed of robust and scaleable cooperating systemic objects.

Visual Basic Sources

References

  1. Brockschmidt, Kraig: Design Considerations for Implementing a Simple OLE Automation Controller. Microsoft Systems Journal, May, 1995.
  2. Brockschmidt, Kraig: How OLE and COM Solve the Problems of Component Software Design. Microsoft Systems Journal, May, 1996.
  3. Brockschmidt, Kraig: How OLE and COM Solve the Problems of Component Software Design, Part II. Microsoft Systems Journal, June, 1996.
  4. Denning, Adam: OLE Controls Inside Out. Microsoft Press. ISBN: 1-55615-824-6.
  5. Armstrong, Tom: Designing and Using OLE Custom Controls. M&T Books. ISBN: 1-55851-445-7

1 When we use the term `workstation', we are referring to any type of computer capable of running a VEE program.
2 Though we focus on the distributed nature of VEE RPC's, there is nothing that prevents the remote function from executing on the same host workstation as the client application.
3 The term `panel' as it is used here is the user interface for a function. Each function may require user input and/or display information.
4 You can name the controls anything you wish; this is the default name Basic assigns.
5 The `random' function returns a random number between the two values, `High' and `Low'; its arguments.