mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 15:22:31 +01:00
Author:halw
Date:2008-09-17T14:29:45.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@4 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -3,14 +3,16 @@
|
||||
We have seen that interfaces can be perceived as views of a component. This conceptual representation actually maps the implementation of an EiffelCOM component since the coclass inherits from the interfaces and implements their deferred features. Indeed, interfaces are deferred classes with all features accessible from outside deferred. The coclass is an Eiffel class that inherits from these interfaces and implements all the features. This design is not specific to Eiffel though and can be found in other languages as well. The coclass defines the behavior of the interface functions. <br/>
|
||||
|
||||
==Class Object==
|
||||
We have seen that interfaces are accessed through interface pointers. But how does a client get hold on one of these?
|
||||
We have seen that interfaces are accessed through interface pointers. But how does a client get hold on one of these?
|
||||
The answer lies in the class object. The name of this module should really be coclass factory since its goal is to spawn instances of the coclass on request. Class objects are accessed by COM whenever a client request a new instance of the associated component. COM loads the class object and asks it to provide the interface pointer requested by the client.
|
||||
|
||||
The way a class object is loaded in memory (this process is called activation) depends on the location of the component (See [[The Component Location|Location]] for a description of the possible locations of a component). If the component is an in-process server then the class object is called directly through the functions exported from the DLL. If the component is an out-of-process server then it provides COM with a pointer to the class object. In both cases, once the component is loaded, COM has access to the class object and can call it would a client request a new instance of a component.
|
||||
[[Image:com-1|Component Creation]]
|
||||
|
||||
[[Image:com-1|Component Creation]]
|
||||
|
||||
The code for the class object is generated by the EiffelCOM wizard so that Eiffel programmers will not have to worry about it.
|
||||
|
||||
{{seealso| '''See Also''' <br/>
|
||||
{{seealso|
|
||||
[[EiffelCOM Wizard|EiffelCOM wizard]] <br/>
|
||||
[[EiffelCOM Library| EiffelCOM library]] <br/>
|
||||
[[EiffelCOM: Introduction| Introduction]] <br/>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
[[Property:title|Deeper into COM]]
|
||||
[[Property:weight|6]]
|
||||
The next paragraph gives some details on the COM internals. The understanding of these details are not required to use the EiffelCOM wizard but might help making better decisions when designing new EiffelCOM components.
|
||||
|
||||
==Apartments==
|
||||
The first interesting subject that requires more in-depth cover is the execution context of a component. Components can be run in the same process as the client but can also run in a separate process even on a different machine.
|
||||
This superficial description only take into accounts processes. What happens if a component uses multithreading to achieve it tasks? In a case of a remote server, this scenario does not seem too esoteric. The problem is that a server does not (and should not) know in advance what its clients will be. It cannot assume that the client will be able to take advantage of its multithreading capabilities. Conversely a multithreaded client should not rely on the server ability to handle concurrent access.
|
||||
|
||||
The solution chosen in the COM specification is to define an additional execution context called an apartment. When COM loads a component it creates the apartment in which the component will run. Multiple instances of a multithreaded component will leave together in the same apartment since asynchronous calls will be handled correctly and there is no need to add any synchronization layer. On the other hand, single threaded component will be alone in their apartment and any concurrent calls coming from clients will be first synchronized before entering the apartment. These two behaviors define two different kinds of apartments: Multi Threaded Apartments (MTA) and Single Threaded Apartments (STA).
|
||||
<div> [[Image:com-2|Apartments]] </div>Apartments solve the problem of concurrency by removing the necessity of knowing the multithreaded capability of a component and its clients. Multithreaded clients can always make asynchronous calls and depending on whether the component handles concurrent access or not, they will be forwarded or first synchronized. There can be multiple instances of STA running in one process while there will be at most one MTA. <span id="marshalling"></span>
|
||||
==Marshaling==
|
||||
At this point you might wonder how calls can "cross" the apartments boundaries. Components from a STA can make calls to components running in a MTA and vice versa. These apartments might be running in different processes or even on different machines. The approach chose in the COM specification is using the proxy and stub patterns.
|
||||
The idea is to trick the client of an interface by providing an interface proxy in its apartment. The proxy include exactly the same function as the interface itself but their implementation will just forward the call to the actual interface. The client has no idea whether the entity it is dealing with is the actual interface or just a proxy. One of the main interest of that approach is that the client implementation is independent from the location of the component.
|
||||
|
||||
Last explanation is not totally accurate: the call will not be forwarded to the actual interface but to its stub. The stub is the counterpart of the proxy, it represents the client for the interface. The interface doesn't know either whether it is communicating with the actual client or a stub. Although it is not totally true that the component implementation is independent from the location of the client, the stub pattern still helps keeping code identical for the implementation of the interface themselves. The implementation of a component will still be different whether it is an in-process or out-of-process component since it will have to be a DLL in one case and a executable in the other. The design of the interfaces might also differ since out-of-process servers will tend to avoid too many round trips.
|
||||
<div> [[Image:com-3|Cross Apartment Calls]] </div>There is one proxy/stub pair per interface. The proxy or the stub is loaded dynamically only when needed. This proxy/stub pair constitute the marshaller. The reason for having a single name for two different things come from how MIDL generates its code. MIDL will produce files for one DLL in which both the proxy and the stub will be included. This DLL is the marshaller. <div>
|
||||
==Summary==
|
||||
This brief introduction to the Component Object Model should be enough to get started with the EiffelCOM wizard. It specifies the main characteristics that define the type of a component and that need to be given to the wizard along with the definition file. </div>
|
||||
{{seealso|
|
||||
[[EiffelCOM Wizard|EiffelCOM wizard]] <br/>
|
||||
[[EiffelCOM Library| EiffelCOM library]] <br/>
|
||||
[[Generalities| Generalities]] <br/>
|
||||
[[Deeper into COM| Deeper into COM]] <br/>
|
||||
[[COM Interfaces| COM Interfaces]] <br/>
|
||||
[[Coclass| Coclasses]] <br/>
|
||||
[[The Component Location| Component Location]] <br/>
|
||||
[[Access Type| Access Type]] }}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user