荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Jobs (温少), 信区: visualBCJ
标  题: Building, Versioning, and Maintaining Visual Basic Components
发信站: BBS 荔园晨风站 (Mon Nov 29 15:22:23 1999), 站内信件



Building, Versioning, and Maintaining Visual Basic Components
For Use in Microsoft Visual Basic, VBScript, C++, and Other Languages
Ivo Salmre
Microsoft Corporation

February 1998

Click to copy the sample files for this technical article.

Contents
Abstract
Goals of Versioned Component Development
OLE Automation Calling Conventions
Overview of Languages
The Visual Basic Public Class
Building Robust Components
Insuring Broad Component Usability
Insuring Broad Component Interoperability
Maintaining Your Components
The Sample
Tips and Common Mistakes
Summary
Other References

Abstract
Microsoft? Visual Basic? makes it easy to build Component Object Model (COM)
components. Without writing a line of code, a programmer can create a new
Microsoft ActiveX? project and compile it into a server. Adding properties and
methods is also similarly easy. Properly maintaining and versioning components
is a more complex endeavor. Doing so is extremely important, because it will
save the time and great frustration that result when misversioned components
break existing applications. To do this, all of the programmer's existing
Visual Basic skills can be leveraged, but a few new guidelines and strategies
must also be learned. This document is an effort to lay out these additional
strategies.

Goals of Versioned Component Development
What does it mean to develop, version, and maintain components? Developing,
versioning, and maintaining components means writing, debugging, deploying, and
maintaining components that run in mission-critical or line-of-business
applications. These applications are designed to automate, simplify, or make
possible tasks of great value to a business or across businesses. Failure or
redesign of these components is costly.

Broad Component Usability
Components derive their strength from their ability to be used widely. This
means ensuring that components you and your team build work well, whether they
are used from Visual Basic, Java, C/C++, Visual Basic Scripting Edition
(VBScript), JavaScript, or any other language.

Robust Component Interoperability
Large systems are built out of many components that interact with each other.
It is important to design components in these systems in such a way that this
interaction is highly usable and robust梩hat is, that components you and your
team build work well with each other.

Maintainability
As business needs evolve and grow, it is important that business systems evolve
with them. Much is needed today, and more will be required tomorrow. To this
end, the components you build need to be able to be upgraded with as little
disruption to the larger business systems as possible. (For example, upgrading
a single component should not require recompiling and redeploying all 60
components in the larger system; it should be upgradable by itself.)

OLE Automation Calling Conventions
In order to understand how to design components that work well in both
scripting and precompiled languages, it is important to understand how
different languages bind to COM objects and access properties and methods on
them.

Early Binding (Compile-Time Binding)
Early binding (also known as VTable binding) is compile-time binding. When an
application that consumes components is compiled, the calls to functions on
those objects (v-table offsets) and the signatures of those functions (number,
type, and order of the parameters) are resolved and compiled into the
application.

Advantages
Fastest possible code.
Because the function calls are resolved at compile time, work does not need to
be done at run time.

Strongest type checking.
Because the parameter types are known, error checking can be done at compile
time.

Disadvantages
Not resilient to function signature changes.
Adding a parameter or changing the order of the functions in the object's
v-table will result in breaking binary compatibility. The user must choose
between breaking compatibility and making these changes.

Scripting languages are not capable of early binding.
Late Binding (Run-Time Binding)
Late binding is run-time binding. Method calls are resolved at run time.

Advantages
Most resilient to function signature changes.
If all of your components are accessing objects from a late-bound perspective
(and this is an important "if"), you have a great deal of liberty to add
parameters and modify parameter types.

Disadvantages
Cumbersome to call from C++/Java.


No compile-time type checking (errors are found at run time).
Overview of Languages
The purpose of building components is good encapsulation and code reuse. COM
makes possible broad reuse of components by different languages. To gain the
maximum benefit of building components, you should design your components to
the needs of the consumers of those components.

C and C++
Technically "everything is possible in C/C++," meaning that you can call any
interface from C/C++, whether it's early bound or late bound, uses variants or
not, and so on. However, just because it is possible doesn't mean that it is
convenient, useful, or prudent. C++ (and C) is a strongly typed language that
works best with strongly typed calling conventions, such as early-binding and
strongly typed variables.

The following partial code shows how to make a late-bound call from C++:

//MISSING: Code to package the parameters in an array of variants (this code
removed in the interest of saving some space).


//Look up the memid of our call
hRes = pDisp->GetIDsOfNames(IID_NULL, &pbstrMethd, 1, NULL, m_lngSyncCallDispID)
;
ON_FAIL_ABORT(hRes);
ON_FALSE_ABORT(m_lngSyncCallDispID != -1);

//Init the return variant structure
VariantInit(&vntRetVal);
//Clear the last result before we get going here
hRes = VariantClear(&m_vntRetVal_SyncCall);

//Since we may be expecting our invoke to cause an error,
//we do not want to propagate an error upward if one occurs.
//instead we want to see if we're expecting an error...
m_hRes_SyncCall = m_pDisp_SyncCall->Invoke(
      m_lngSyncCallDispID,   //ID of method we're calling
      GUID_NULL,            //Must be NULL
      0,                  //lcid: Don't care...
      DISPATCH_METHOD | DISPATCH_PROPERTYGET,
      &m_dispparams,         //struct containing the parameters we're passing
      &vntRetVal,            //return value
      &m_SyncMethod_ExcepInfo,//struct to store expection info in
      &uArgErr);            //Argument that caused Invoke to fail (i.e. arg
type incorrect)

The following shows the code to make an early-bound call from C++:

hRes = m_SomeObject->SomeMethod(firstParameter, secondParameter);

As you will probably agree, early binding is considerably easier to use from C
or C++.

J++: Strongly Typed
Java, much like C++, is a strongly typed language, generally binding to objects
and interfaces at compile time. Its variables also are generally strongly typed.

Java takes only by value parameters for functions. You may not return values
via function parameters.

Note   Can functions with by-ref parameters be called in Java? Yes, but it is
awkward to do so. The by-reference variables must be declared as one-element
arrays in Java in order to pass them as by reference to functions that require
by-reference parameters. You should avoid by-reference parameters if you want
to make using your objects simple for Visual J++? programmers.

These comments refer to using Visual J++ version 6.0 and later. COM/Java
interactions using Java compilers other than the Microsoft Visual J++ compiler
will have different levels of COM support.

Microsoft Visual Basic : Jack of All Trades
Microsoft Visual Basic was designed with COM and, specifically, Automation in
mind. Not surprisingly, it offers the richest possible experience for calling
components. Visual Basic is capable of easily binding to objects at compile
time or run time:

Early and late binding using Visual Basic
The following code shows early binding to an object:

Dim objXL as Excel.Application 'Interface bound to the Excel.Application
interface
Set objXL = CreateObject("Excel.Application") 'Create the object & bind it to
the Excel.Application interface.
Dim objWB as Excel.Workbook 'Interface bound to the Excel.Workbook interface
Set objWB = objXL.Workbooks.Add 'Create a workbook object & bind to the
interface

Note   All object calls are resolved at compile time.

The following code shows late binding to an object:

Dim objXL as Object  'Late Binding interface
Set objXL = CreateObject("Excel.Application") 'Create the object & bind it to
the Excel.Application interface.
Dim objWB as Object 'Late Binding interface
Set objWB = objXL.Workbooks.Add 'Create a workbook object & bind to the
interface

Note   All object calls are resolved at run time.

What is the moral of the story? The user code for late-bound and early-bound
calls is almost identical in Visual Basic.

Polymorphism in Visual Basic
Polymorphism is the ability of an object to support multiple interfaces. Visual
Basic makes it easy to bind to multiple interfaces in an object. Binding to an
interface is done via the Visual Basic Set keyword.

For example:

Sub Foo (obj as Object)
Dim myCar as Car
Dim myTruck as Truck

'Takes the object (unknown type) and gets the Car inteface
Set myCar = obj

'Querys the object for the Truck interface
Set myTruck = myCar

'Querys the object for the Truck interface (same as above)
Set myTruck = obj

End Sub

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.11.111]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店