Delphi provides wizards to help you create various COM objects. This chapter provides an overview of how to create a simple, lightweight COM object, such as a shell extension, in the Delphi environment. To create Automation client and server objects, see "Creating an Automation controller," and "Creating an Automation server." To create an ActiveX control, see "Creating an ActiveX control." To create an Active Server Page, see "Creating an Active Server Page."
This chapter is not intended to provide complete details of writing COM applications. For that information, refer to your Microsoft Developer's Network (MSDN) documentation. The Microsoft Web site also provides current information on this topic.
Use the COM object wizard to create a simple, lightweight COM object, for example, a shell extension. A COM object can be implemented as either an in-process server, out-of-process server, or remote server.
The COM object wizard performs the following tasks:
The process of creating a COM object involves these steps:
When designing the COM object, you need to decide what COM interfaces you want to implement. The wizard supplies the IUnknown interface. If you want to implement any other COM interfaces, see the MSDN documentation.
You must decide whether the COM object is an in-process server, out-of-process server, or remote server. For in-process servers and for out-of-process and remote servers using a type library, COM marshals the data for you. Otherwise, you must consider how to marshal the data to out-of-process servers.
For information on server types, see"In-process, out-of-process, and remote servers".
Before you create a COM object, create or open the project for an application containing functionality that you want to implement. The project can be either an application or ActiveX library, depending on your needs.
To bring up the COM object wizard,
In the wizard, specify the following:
Specify an instancing mode to indicate how your COM object is launched. See "COM object instancing types" for details. Note: When your COM object is used only as an in-process server, instancing is ignored. | |
Choose the threading model to indicate how client applications can call your COM object's interface. For details, see "Choosing a threading model". Note: The threading model you choose determines how the object is registered. You must make sure that your object implementation adheres to the model selected. | |
Specify the names of the COM interfaces that you want this COM object to implement. | |
Check this box to generate a type library for this object. A type library contains type information that allows you to expose any object interface and its methods and properties to client applications. Checking this box automatically causes Mark Interface OleAutomation to be checked. | |
Check this box to enable the marshaling code that gets generated when you create a type library. COM knows how to marshal all the Automation-compatible types in the type library and can set up the proxies and stubs for you so that you can pass parameters to out-of-process (.EXE) servers. For more information, see "The marshaling mechanism". |
Note: Instancing is ignored when your COM object is used only as an in-process server.
When your COM application creates a new COM object, it can have any of the following instancing types:
When creating an object from the wizard, you select a threading model that your object agrees to support. By adding thread support to your COM object, you can improve its performance.
Table 45.1 lists the different threading models you can specify.
Both the client and server sides of the application tell COM the rules it intends to follow for using threads when it initializes COM. COM compares the threading rules that each party has agreed to support. If both parties support the same rules, COM sets up a direct connection between the two and trusts that the parties follow the rules. If the two parties advertise different rules, COM sets up marshaling between the two parties so that each sees only the threading rules that it says it knows how to handle. Of course, marshaling affects performance somewhat, but it allows parties with different threading models to work together.
Note: The threading model you choose in the wizard determines how the object is advertised in the registry. You must make sure that your object implementation adheres to the threading model you have chosen.
The threading model is valid for in-process servers only. Setting the threading model in the wizard sets the threading model key in the CLSID registry entry, InProcessServer32.
Out-of-process servers are registered as EXE and it is up to you to implement the threading model yourself. If the EXE contains a free threaded server, Delphi will initialize COM for free threading, which means that it can provide the expected support for any free-threaded or apartment-threaded objects contained in the EXE. To manually override threading behavior in EXEs, see the CoInitFlags variable in online Help.
Note: Local variables are always safe, regardless of the threading model. This is because local variables are stored on the stack and each thread has its own stack.
Use the free threading model rather than apartment threading whenever the object needs to be accessed from more than one thread. A common example is a client application connected to an object on a remote machine. When the remote client calls a method on that object, the server receives the call on a thread from the thread pool on the server machine. This receiving thread makes the call locally to the actual object; and, because the object supports the free threading model, the thread can make a direct call into the object.
If the object supported the apartment threading model instead, the call would have to be transferred to the thread on which the object was created, and the result would have to be transferred back into the receiving thread before returning to the client. This approach requires extra marshaling.
To support free threading, you must consider how instance data can be accessed for each method. If the method is writing to instance data, you must use critical sections or some other form of serialization, to protect the instance data. Likely, the overhead of serializing critical calls is less than executing COM's marshaling code.
Note that if the instance data is read-only, serialization is not needed.
To implement the (single-threaded) apartment threading model, you must follow a few rules;
The single-threaded apartment model is the middle ground between providing no threading support and full, multi-threading support of the free threading model. A server committing to the apartment model promises that the server has serialized access to all of its global data (such as its object count). This is because different objects may try to access the global data from different threads. However, the object's instance data is safe because the methods are always called on the same thread.
Typically, controls for use in Web browsers use the apartment threading model because browser applications always initialize their threads as apartment.
For general information on threads, see "Writing multi-threaded applications."
After you have created your COM object, you must register it so that other applications can find and use it.
Note: Before you remove a COM object from your system, you should unregister it.
As an alternative, you can use the tregsvr command from the command line or run the regsvr32.exe from the operating system.
Testing your COM object depends on the COM object you have designed. Once you have created the COM object, test it by using the interfaces you implemented to access the methods of the interfaces.
To test and debug a COM object,
The COM object pauses when the breakpoints are reached.
pubsweb@inprise.com
Copyright © 1999, Inprise Corporation. All rights reserved.