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:
- Language Independence
- Interoperation with Other System Facilities
- Network Transparency
- Painless Resource Discovery
- Ubiquity
- Easy Adoption
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
- Events
- Methods
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:
- Identify a workstation you wish to execute your HP VEE
function.
- Explore libraries of functions, extracting information
about each individual function.
- Build call and return stacks that specify HP VEE function
arguments and return values.
- Call a function either synchronously or asynchronously.
- Determine the state of an asynchronous function call.
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
- Brockschmidt, Kraig: Design Considerations
for Implementing a Simple OLE Automation Controller. Microsoft
Systems Journal, May, 1995.
- Brockschmidt, Kraig: How OLE and COM Solve the Problems
of Component Software Design. Microsoft Systems Journal, May,
1996.
- Brockschmidt, Kraig: How OLE and COM Solve the Problems
of Component Software Design, Part II. Microsoft Systems Journal,
June, 1996.
- Denning, Adam: OLE Controls Inside Out. Microsoft Press.
ISBN: 1-55615-824-6.
- 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.