Vbcom tutorial (3)

zhaozj2021-02-17  83

COM CLASSES AND SERVERS

Introduction

In Visual Basic, building a COM-compatible object is deceptively easy: given the class definition for this object, you simply add the class to a particular type of VB project, make the project, and you're done That's it, end of. Tutorial! In Reality of Course, There's More To VB Com Than Just Doing Make.

First, let's define some standard COM terminology. A coclass refers to a COM class, ie a class that is compatible with COM. What makes VB so powerful is that all classes created in VB are COM-compatible. It will be helpful if you also ......................... ..

A COM server is one or more coclasses compiled into a single, distributable file. COM servers typically have the file extension .dll or .exe. A COM server must be registered on a client's machine before that client can instantiate any of the coclasses in the Server.

There are two types of COM servers, in-process and out-of-process. If a client instantiates a coclass from an in-process COM server, the resulting object lives in the same address space (and process) as the client. However , if a client instantiates a coclass from an out-of-process COM server, the resulting object will live and run in a separate process --- on the same machine (local) or a different machine (remote). To build an in -process COM server in VB, you create an ActiveX DLL project, add one or more class modules, and perform make; the result is a file with the extension .dll To build an out-of-process COM server, use an ActiveX. EXE Project Type; Make Will Then Yield a file with the extension .exe.

In-Process VB COM ServersThe extension DLL stands for Dynamic Link Library, implying that an in-process COM server is linked into the client upon the first instantiation of any of its coclasses. Note that the entire COM server is linked in, not just the Coclasses Being Instantiated. for Example, Suppose A CoM Server Has 3 Coclasses, And A Client Instantiates Coclass1 and Coclass2. Here's The Resulting Situation In Memory On That Machine:

Now Suppose The User, On this Same Machine, Starts Up Another Process Called Client # 2 That Instantiates Coclass3. Conceptually, The Situation In Memory is now:

In essence, each process gets its own copy of COM Server. Why is this important? Because if COM Server contains "global" variables, it is important to note that these variables are not shared by the different client processes.

Out-of-process VB COM Servers

As we all know, the extension EXE stands for executable program. Thus, out-of-process COM servers are completely separate processes, running asynchronously until a client makes a method call into one of the server's objects (at which point the client object blocks . until the server object returns from the method call) For example, suppose we have an out-of-process COM server with 3 coclasses, and a client object on the same machine instantiates coclass2 The situation in memory is.:

What if Multiple Clients Instantiate Coclasses from The Same COM Server? Typically Yields a Different Object Withnin The Same Server Process:

However, whether these server objects run concurrently --- ie whether method calls from different clients execute at the same time --- depends on how the COM server is configured; we'll save this topic for later, when we discuss COM activation. note that the configuration of the COM server controls other things as well in particular, whether or not:. (1) the different server objects in the above picture can share "global" variables, and (2) instantiation yields multiple objects in the same Server (AS Shown Above) or an entirely new server process each time (thus # of processes = # of server objects).

Lab: Building VB COM Servers

Time for a lab exercise! The goal is to take an existing application, remove one of its classes, turn that class into a COM component, and produce a new, COM-based application. First we'll build an ActiveX DLL COM server, then repeat the exercise by building an ActiveX EXE COM server. The application simulates a long-running operation, displaying a progress indicator as it proceeds. Here's a picture of the app, which you can see this for yourself by running / VBCOM / Labs / COM Servers / App.exe (if you have not already DONE SO, You Can Download The Labs from The Setup Page):

IT is The program, defined by the class cprogress in / vbcom / labs / com servers / app.vbp, That Will Become a ComPonent.

Startup VB, and create a new ActiveX DLL project VB will define an initial class module called Class1 Select this class, and remove it from the project (Project >> Remove);... When prompted, do not save changes Now add the existing class module file "CProgress.cls" to the project: Project >> Add class Module, existing tab, navigate to / VBCOM / Labs / COM Servers / CProgress.cls, and open Likewise, add the existing form "frmProgress.frm". to the project. Take a moment and review the code in CProgress. For help understanding this code, jump here. View the project explorer (View >> Project Explorer), expand the Class Modules, and select CProgress. View the properties window (F4 ), and change the Instancing property from Private to MultiUse. This makes the COM coclass publicly accessible to clients. Modify the project's properties (a very important step when building a COM server) via Project >> Properties. Under the General tab, set the Name to "Progressdll" and the description to "_P rogress Indicator In-Process Server (VBCOM) ". Click OK. Finally, make your COM server via File >> Make, into the same directory as the other files. Save your work, and exit VB.Congratulations, you have just built your ! first COM server your COM server resides in the file "ProgressDLL.dll" that you made; if you can not see this file in your lab directory, make sure your explorer window is set to display hidden files Now, to test your work,. Let's build aclient application.

Startup VB, and create a new Standard EXE project Remove the initial form module Form1, and add the existing form / VBCOM / Labs / COM Servers / frmMain.frm Modify the project's properties:.. Set the startup object to be frmMain, and the name to "Client" Click OK View the form, in particular the code behind the cmdProgress command button The sub creates an instance of CProgress, shows progress in increments of 10, and then destroys the instance:... Dim i As IntegerDim j As Variant Dim progress As CProgress Set progress = New CProgress' ** instantiate COM component progress.Show '** tell component to show itself For i = 1 to 10' ** update progress progress.Value = progress.Value 10 For j = 1 to 1000000: Next J '** Pause to Simulate Operation Next I Progress.hide Set Progress = NOTHING' ** Destroy Comssent

Now run the application (F5). Depending on how VB is configured on your machine, you will either get an immediate compiler error ( "User-defined type not defined", with CProgress highlighted), or the app will startup and show the main . form In the latter case, clicking the button will then yield the same error message: "User-defined type not defined" The problem is that our new client application is unable to locate the class CProgress Whenever you want to use a COM.. component, you must first reference it so that VB can find it. Thus, view the list of registered COM components on your machine (Project >> References), and select the progress indicator component we built earlier --- ie check the item " _Progress Indicator in-Process Server (VBCOM) ". Click OK. Now re-run the application. It should work perfectly, merrily showing progress in increments of 10! Finally, make an executable" Client.exe ", save your work, and EXIT VB.You SHOULD Be Able To Run "Client.exe" Outside of VB, and it should run identically to "App.exe". However, the former uses COM, and the later does not. If you want to run multiple clients and view multiple progress indicators on the screen, you will need to add a call to DoEvents Inside the client's for-next loop, and perhaps pause a bit Longer as Well.

At this point, it is very important to observe the following: no special programming was required to use COM with VB The only differences from the original "App.exe" were configuration-oriented --- the use of a different project type in! .....................

For completeness, let's build the progress indicator into an out-of-process COM server Once again, the only changes will be the use of a different project type for the server, and a different project reference in the client:. Repeat steps 1. . 6 above, except create an ActiveX EXE project, set the project name "ProgressEXE" and the description to "_Progress Indicator Out-of-Process Server (VBCOM)". After you make your project, you should end up with a COM server in the file "ProgressEXE.exe". Reopen the "Client.vbp" project, and under project references uncheck the in-process COM server and check your new "_Progress Indicator Out-of-Process Server (VBCOM)". Now run your ! client (F5), and it should function as before To convince yourself that the COM server actually runs as a separate executable, insert a Stop statement in the client immediately after the instantiation of CProgress:

Set progress = new cprogress '** instantiate component stop program.show' ** Tell COM inent to show itself

Now Run The Client from Inside VB, And Click The Command Button to Execute The Above Code. VB Should Enter Break Mode with the

STOP Statement Highlighted. Bring Up The Task Manager On Your Computer, And you will see That

Progressexe is Running! Switch Back to VB, Continue Execution, And Let The Client Run (I.E. Let the Processing of

CMDProgress's Click Event Run To Completion). Return Back to The Task Manager, And Observe That

ProgressExe Is No longer Running. Why not? Because The Client No longer Has A Reference To A

CPROGRESS Object, And When The Last Object In a VB Com Server is destroyed the server is stopped.

If you want to play ... To keep the COM server running, we need to keep at least one object alive in the server. This means we need to keep the object's reference count> 0. One way to do this in our clients is to keep object references in global variables, which never go out of scope. in the client app, first move the declaration of the progress variable from the Click event to the Declarations section (top) of the main form. Then, instead of instantiating CProgress in the Click event, now do this in the form's Load event. Finally, move the "Set progress = Nothing" statement from the Click event to the form's Unload event. now when you run the client, the COM server will be started as well And this Same Process Will Continue To Run Until The Client Terminates. Confirm this Behavior Using The Task Manager.that's Enough Lab Work for Now, Good Job!

Registering a VB COM Server

As mentioned in the introduction, a COM server must be registered before a client can instantiate any of the coclasses in that server. However, in the above lab the client app (eg "Client.exe") ran just fine without any kind of explicit "Registration" Step. How Can This BE? WHO REGISTERED TOES IT INDICATOR COM Component to be registered?

In short, registering a COM server means updating the Windows registry database on that computer. The registry enables COM to locate coclasses in response to client instantiation requests. To ease component development, VB automatically registers --- on your development machine --- any COM server you make (ie File >> Make). Thus, each time you do make, VB unregisters the previous version (if any) and registers the new version.As evidence, let's break the "Client.exe" application by simply unregistering . the COM server on which it depends First, in preparation, locate the file /VBCOM/Misc/regsvr.reg and double-click to execute; this file adds some entries to your registry database that makes server registration and unregistration easier Next,. run your "Client.exe" in the lab directory / VBCOM / Labs / COM Servers / and convince yourself that it shows progress without error. Now right-click on the file "ProgressDLL.dll" --- the in-process progress indicator COM Server --- and select " Unregister COM Server "from the pop-up menu Finally, re-run." Client.exe "and click the command button to show progress: this should yield" Run-time error 429: ActiveX component can not create object "In. other words, the requested COM server is not registered on this machine [Note:.. if you did not receive an error, perhaps your client is instantiating the out-of-process version of the progress indicator Unregister "ProgressEXE.exe" and try ]...................

How can you find out what COM servers are registered on your machine One way is to view project references Startup VB, select Project >> References, and you should see something similar to:?. This list is produced by VB using information culled from the Machine's Registry Database; Recall We buy this Dialog in the lab to configure the client.

COM Servers Can Also Be Registered Via The Command-Line. To Register / Unregister An In-Process COM Server, Use The Regsvr32 Utility:

Regsvr32 progressdll.dll Regsvr32 / u progressdll.dll

In the case of out-of-process com servers, Run The Server Itself:

ProgressExe.exe / regserver progressexe.exe / unregserver

.....................................

For now, we can safely ignore the registration problem since VB will automatically register COM servers for us. However, you need to keep this in mind when it comes time for deployment. We will revisit this issue in more detail when we present COM activation.

In-Process vs. Out-of-process?

When developing a COM component, you are faced with an immediate decision:? Create an in-process server, or an out-of-process server The short answer is that in-process COM servers offer better performance while out-of-process COM servers offer greater flexibility. The former are more efficient since the server objects live in the same address space as the client, enabling a much cheaper communication mechanism (a simple subroutine call). The latter are more flexible since they can be deployed remotely on server Machines, Withnout Having to Recompile Any of The Code.

At first glance, it would appear that multi-tier applications are best designed using out-of-process COM servers. However, it is becoming quite common to develop in-process COM servers and then deploy these components using surrogate processes. A surrogate process acts as a host for an in-process COM server, allowing it to run in an address space separate from the client --- just like an out-of-process COM server. However, the advantage is that the surrogate can provide services to its server objects, such as support for sharing state (ie "global variables"). The most important example of a surrogate process is Microsoft Transaction Server (MTS), which among other things provides support for distributed transactions. Thus, if you want to Build Comss, You Must Create In-Process COM Servers.What's next? a Discussion of Client-Side CoM Programming.

转载请注明原文地址:https://www.9cbs.com/read-31409.html

New Post(0)