In [[informatica]] il '''Component Object Model''' (noto con l'[[acronimo]] '''COM''', [[Lingua inglese|inglese]] per ''Modello a oggetti per componenti'') è un'[[interfaccia (programmazione)|interfaccia]] per componenti [[software]] introdotta da [[Microsoft]] nel [[1993]]. COM permette la [[comunicazione tra processi]] e creazione dinamica di oggetti con qualsiasi [[linguaggio di programmazione]] che supporta questa tecnologia.<ref>{{cita web|url=https://www.microsoft.com/com/|titolo=Component Object Model Technologies|editore=Microsoft Corporation}}</ref> Il termine COM è spesso usato nel mondo dello sviluppo software con più significati: [[Object Linking and Embedding|OLE]], [[OLE Automation]], [[ActiveX]], COM+ e [[Distributed Component Object Model|DCOM]]. Nonostante l'introduzione di COM risalga al 1993, Microsoft ha iniziato ad utilizzare con enfasi questo nome solamente nel [[1997]].
{{da tradurre|inglese|maggio 2006}}
Il '''Component Object Model''' ('''COM''') è una [[piattaforma (informatica)|piattaforma]] di [[Microsoft]] per componenti software introdotta da Microsoft nel [[1993]]. COM permette la [[comunicazione tra processi]] e creazione dinamica di oggetti con qualsiasi [[linguaggio di programmazione]] che supporta questa tecnologia. Il termine COM è spesso usato nel mondo dello sviluppo software con più significati: [[Object Linking and Embedding|OLE]], [[OLE Automation]], [[ActiveX]], COM+ e [[Distributed Component Object Model|DCOM]]. Nonostante l'introduzione di COM risalga al 1993, Microsoft ha iniziato ad utilizzare con enfasi questo nome solamente nel [[1997]].
Sebbene sia stato [[Portabilità|portato]] anche su altre piattaforme, COM è utilizzato principalmente con [[Microsoft Windows]]. Si prevede una progressiva sostituzione almeno parziale di COM da parte del [[framework]] [[Microsoft .NET]].
==Storia==
[[Anthony Williams]], una delle principali menti coinvolte nella creazione dell'architettura COM, distribuì un paio di documenti Microsoft interni che trattavano il concetto di componenti software; "''Object architecture: dealing with the unknown - or - Type safety in a dynamically extensible class''" ("''Architettura di un oggetto: trattare l'ignoto - o - Sicurezza dei tipi in una classe dinamicamente estensibile''") nel [[1988]] e "''On inheritance: what it means and how to use it''" ("''Sull'ereditarietà: cosa significa e come si usa''") nel [[1990]]. Questi gettarono le basi per molte, se non tutte, delle idee dietro ai fondamenti di COM.
Da molte di quelle idee nacque il primo [[framework]] ad oggetti di Microsoft, [[Object Linking and Embedding|OLE]] ([[acronimo]] dell'[[Lingua inglese|inglese]] ''Object linking and embedding'', sta per ''Collegamento ed incorporazione di oggetti''). OLE fu costruito partendo dal [[Dynamic Data Exchange|DDE]] e progettato con un occhio di riguardo per i [[Documento composito|documenti compositi]]; fu introdotto per la prima volta con [[Microsoft Word|Word per Windows]] ed [[Microsoft Excel|Excel]] nel [[1991]], e fu successivamente incluso in Windows, a partire dalla versione [[Windows 3.x|3.1]] del [[1992]].
Nel 1991 Microsoft introdusse la tecnologia [[Visual Basic Extension|VBX]] (acronimo di ''Visual Basic extension'', ''Estensione di Visual Basic'') con [[Visual Basic]] 1.0.
Nel [[1993]] Microsoft rilasciòdistribuì OLE 2, avente COM come modello a oggetti sottostante. Mentre OLE 1 era focalizzata sui documenti compositi, COM ed OLE 2 avevano un indirizzo più generico. Nel [[1994]] furonifurono introdotti i controlli OLE ([[OCX]], ''[[OLE controlControl extension''eXtension]], cioè ''Estensione controllo OLE'') quali naturali successori dei controlli VBX; al tempo stesso, Microsoft annunciò che OLE 2 sarebbe stato chiamato semplicemente "'''OLE'''", e che questo non sarebbe più stato un acronimo, ma un vero e proprio nome con cui la compagnia avrebbe indicato le proprie tecnologie ad oggetti.
Successivamente, nell'inizio del [[1996]], Microsoft cambiò nome ad alcune parti di OLE relative ad [[Internet]] in '''[[ActiveX]]''', iniziando così quel processo che l'ha portata a rinominare negli anni tutte le tecnologie OLE in ActiveX, con la sola eccezione della tecnologia di documenti compositi impiegata in [[Microsoft Office]].
Più tardi, in quell'anno, Microsoft rilasciòdistribuì [[Distributed Component Object Model|DCOM]] (acronimo di ''Distributed component object model'', inglese per ''Modello ad oggetti per componenti distribuiti'') quale risposta a [[CORBA]].
==Struttura e funzionamento di COM==
==Tecnologie correlate==
Lo scopo del Component Object Model è quello di permettere la creazione di componenti software binari: sebbene sia stato creato avendo in mente il linguaggio [[C++]], COM è neutrale rispetto al linguaggio di programmazione, cioè si può usare qualunque linguaggio di programmazione per usare componenti COM a runtime. Questa neutralità è ottenuta specificando i formati dei dati e delle chiamate a funzioni con il linguaggio [[Interface Description Language|IDL]], del tutto indipendente. Concettualmente quindi, è un passo in avanti ulteriore rispetto alle librerie a collegamento dinamiche ([[DLL]]). Ogni oggetto COM deve essere unico all'interno del sistema, e viene usato attraverso '''interfacce''' software anche loro globalmente uniche.
COM è stata la principale piattaforma di sviluppo software per Windows e, in quanto tale, ha influenzato lo sviluppo di una serie di tecnologie a supporto.
Per assicurare l'unicità, il programmatore che crea un nuovo oggetto COM crea un [[GUID]] per lui (un numero identificativo di 128 bit, generato casualmente e che è, ''quasi'' sicuramente, diverso da ogni altro GUID nel sistema) e un GUID per ciascuna delle interfacce che l'oggetto implementa; questi GUID vengono detti CLSID (class ID) se si riferiscono a un oggetto COM e IID (interface ID) se si riferiscono a un'interfaccia. Affinché sia possibile usare un oggetto COM, questo deve essere registrato in Windows nel [[registro di sistema]], vale a dire viene creata una voce nel registro che associa il CLSID del componente al file su disco che lo implementa fisicamente, e a eventuali informazioni di configurazione. Quando un programma richiede un dato componente COM, fa riferimento al CLSID corrispondente: Windows si occuperà di trovare il file su disco (DLL o [[Eseguibile EXE|EXE]]) e caricare il codice necessario. Fatto questo, il programma chiederà al componente appena creato l'accesso a una delle sue interfacce, usando l'IID di quella che gli serve.
===COM+===
<!--
With [[Windows 2000]], a significant extension to COM named '''COM+''' was introduced. At the same time, Microsoft de-emphasized [[DCOM]] as a separate entity. Transactional COM components formerly deployed on Windows NT4 using the Microsoft Transaction Server application interface were now handled more directly by the added layer of COM+. COM+ components were now added through the Component Services application interface.
An advantage of COM+ was that it could be run in "component farms". A component, if coded properly, could be reused by new calls to its initializing routine without unloading it from memory. Components could also be distributed (called from another machine) as was previously only possible with DCOM.
-->
===DCOM===
<!--
''Main article: [[Distributed component object model]]''
-->
===.NET===
<!--
The COM platform has largely been superseded by the [[.NET Framework|Microsoft .NET]] initiative, and Microsoft now focuses its [[marketing]] efforts on .NET. To some extent, COM is now [[deprecation|deprecated]] in favour of .NET. Despite this, COM remains a viable technology with an important software base – for example the popular [[DirectX]] 3D rendering [[software development kit|SDK]] is based on COM. Also, a COM component should theoretically always have better performance than a matching managed .NET component. As of this writing, Microsoft has no plans for discontinuing either COM or support for COM.
Several of the services that COM+ provides, such as [[transaction|transactions]] and [[queue|queued components]], are still important for enterprise .NET applications.
There is limited support for backward compatibility. A COM object may be used in .NET by implementing a ''runtime callable wrapper'' (RCW). [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconRuntimeCallableWrapper.asp] .NET objects that conform to certain interface restrictions may be used in COM objects by calling a ''COM callable wrapper'' (CCW). [http://msdn2.microsoft.com/f07c8z1c.aspx] From both the COM and .NET sides, objects using the other technology appear as native objects.
.NET's remoting model solves a number of COM's remote execution shortcomings, allowing objects to be transparently marshalled by reference or value across process or machine boundaries.
-->
==Sicurezza su Internet==
<!--
Microsoft's idea of embedding active content on web pages as COM/ActiveX components (rather than, say, Java applets) created a combination of problems in the [[Internet Explorer]] web browser that has led to an explosion of [[computer virus]], [[Trojan horse (computing)|trojan]] and [[spyware]] infections. These [[malware]] attacks mostly depend on ActiveX for their activation and propagation to other computers. Microsoft recognized the problem with ActiveX as far back as 1996 when Charles Fitzgerald, program manager of Microsoft's Java team said "If you want security on the 'Net', unplug your computer. ... We never made the claim up front that ActiveX is intrinsically secure."
[http://www.javaworld.com/javaworld/jw-03-1997/jw-03-component.web97.html]
As COM and ActiveX components are run as native code on the user's machine, there are fewer restrictions on what the code can do. Many of these problems have been addressed by the relative deprecation of COM in platforms developed since such as the [[Java platform]], and later by the [[.NET Framework|.NET]] platform as well.
-->
==Dettagli tecnici==
<!--
COM programmers build their software using COM-aware [[component|components]]. Different component types are identified by class IDs (CLSIDs), which are [[Globally Unique Identifier|Globally Unique Identifiers]], or GUIDs. Each COM component exposes its functionality through one or more [[interface (computer science)|interfaces]]. The different interfaces supported by a component are distinguished from each other using interface IDs (IIDs), which are also [[Globally Unique Identifier|GUIDs]].
COM interfaces have [[binding (computer science)|bindings]] in several languages, such as [[C programming language|C]], [[C++]], [[Visual Basic]], and several of the scripting languages implemented on the Windows platform. All access to components is done through the [[methods]] of the interfaces. This allows techniques such as inter-process, or even inter-computer programming (the latter using the support of [[DCOM]]).
-->
===Interfacce===
<!--
All COM components must (at the very least) implement the standard <code>[[IUnknown]]</code> interface. Indeed, all COM interfaces are [[Inheritance (computer science)|derived]] from the <code>IUnknown</code> interface. The <code>IUnknown</code> interface consists of three methods: <code>AddRef()</code> and <code>Release()</code>, which implement [[reference counting]] and controls the lifetime of interfaces; and <code>QueryInterface()</code>, which by specifying an IID allows a caller to retrieve references to the different interfaces the component implements. The effect of <code>QueryInterface()</code> is similar to <code>dynamic_cast<></code> in [[C++]] or [[cast (computer science)|casts]] in [[D programming language|D]], [[Java programming language|Java]] and [[C Sharp programming language|C#]].
A COM component's interfaces are required to exhibit the reflexive, symmetric, and transitive properties. The reflexive property refers to the ability for the <code>QueryInterface()</code> call on a given interface with the interface's ID to return the same instance of the object. The symmetric property requires that when interface B is retrieved from interface A via <code>QueryInterface()</code>, interface A is retrievable from interface B as well. The transitive property is similar to the symmetric property, but requires that if interface B is obtainable from interface A and interface C is obtainable from interface B, then interface C should be retrievable from interface A.
An interface consists of a pointer to a [[virtual function table]] that contains a list of pointers to the functions that implement the functions declared in the interface, in the same order that they are declared in the interface. This technique of passing structures of function pointers is very similar to the one used by [[Object linking and embedding|OLE 1.0]] to communicate with its system libraries.
COM specifies many other standard interfaces used to allow inter-component communication. For example, one such interface is <code>IStream</code>, which is exposed by components that have data stream [[semantics]] (e.g. a <code>FileStream</code> component used to read or write files). It has the expected <code>Read</code> and <code>Write</code> methods to perform stream reads and writes. Another standard interface is <code>IOleObject</code>, which is exposed by components that expect to be linked or embedded into a container. <code>IOleObject</code> contains methods that allow callers to determine the size of the component's bounding rectangle, whether the component supports operations like 'Open', 'Save' and so on.
-->
===Classi===
<!--
A class in COM is referred to as a '''coclass'''. A '''coclass''' is COM's (language-independent) way of defining a class (in the object-oriented sense).
A coclass supplies '''concrete''' implementation(s) of one or more interfaces. In COM, such concrete implementations can be written in any programming language that supports COM component development, e.g. C++, Visual Basic, etc.
One of COM's major contributions to the world of Windows Development is the awareness of the concept of : '''separation of interface from implementation'''. This awareness has no doubt influenced the way programmers build systems today. An extension of this fundamental concept is the notion of : '''one interface, multiple implementations'''. By this, we mean that at runtime, an application can choose to instantiate an interface from one of many different concrete implementations.
-->
===Linguaggio di definizioe di interfacce e librerie di tipi===
<!--
As mentioned earlier, type libraries contain metadata that represent COM types. However, these types must first be described using the text-based '''Interface Definition Language (IDL)'''. After that, the IDL contents are saved into a text file ready to be '''compiled''' (more on this later).
This is the common practice in the development of a COM component, i.e. to start with the definition of types using IDL. An IDL file is what COM provides that allows developers to define object-oriented classes, interfaces, structures, enumerations and other user-defined types in a language independent manner.
An IDL file is compiled by the '''MIDL''' compiler into a type library (.TLB file). The binary metadata contained within the type library is meant to be processed by various language compilers (e.g. VB, VC++, Delphi, etc). The end result of such .TLB processing is that the specific language compiler produces the language-specific constructs (VB classes for VB, C++ classes, various structs, macros and typedefs for VC++, etc) that represent the coclass defined in the .TLB (and ultimately that which was defined in the originating IDL file).
-->
===COM: un framework per oggetti===
<!--
The fundamental principles of COM have their roots in Object-Oriented philosophies. It is a platform for the realization of Object-Oriented Development and Deployment.
Because COM is a runtime framework, types have to be individually identifiable and specifiable at runtime. To achieve this, '''globally unique identifiers''' ('''GUIDs''') are used. Each COM type is designated its own GUID for identification at runtime (viz compile time).
In order that information on COM types be accessible at both compile time and runtime, COM presents the type library. It is through the effective use of type libraries that COM achieves its capabilities as a dynamic framework for the interaction of objects.
Consider the following example coclass definition in an IDL :
<pre>
coclass MyObject
{
[default] interface IMyObject;
[default, source] dispinterface _IMyObjectEvents;
};
</pre>
The above code fragment declares a COM class named MyObject which must implement an interface named IMyObject and which supports (not implement) the event interface _IMyObjectEvents.
Ignoring the event interface bit, this is conceptually equivalent to defining a C++ class like this :
<pre>
class CSomeObject : public ISomeInterface
{
...
...
...
};
</pre>
where ISomeInterface is a C++ virtual class.
Referring once again to the MyObject COM class : once a coclass definition for it has been formalized in an IDL, and a Type Library compiled from it, the onus is on the individual language compiler to read and appropriately interpret this Type Library and then produce whatever code (in the specific compiler's language) necessary for a developer to implement and ultimately produce the binary executable code which can be deemed by COM to be of coclass MyObject.
Once an implementation of a COM coclass is built and is available in the system, next comes the question of how to instantiate it. Now, in languages like C++, we can use the CoCreateInstance() API in which we specify the CLSID (CLSID_MyObject) of the coclass as well as the interface (specified by the IID IID_IMyObject) from that coclass that we want to use to interact with that coclass. Calling CoCreateInstance() like this :
<pre>
CoCreateInstance
(
CLSID_MyObject,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMyObject,
(void**)&m_pIMyObject
);
</pre>
is conceptually equivalent to the following C++ code :
===Le interfacce===
<pre>
Una interfaccia COM è una collezione di funzioni: vale a dire, è una ''classe virtuale pura'', e nella programmazione ad oggetti viene in genere modellata così. Tutte le componenti COM devono come minimo implementare l'[[interfaccia (informatica)|interfaccia]] standard <code>[[IUnknown]]</code>. Infatti, tutte le interfacce COM sono [[Ereditarietà (informatica)|derivate]] dall'interfaccia <code>IUnknown</code>. Essa consiste in tre [[Metodo (programmazione)|metodi]]: <code>AddRef()</code> e <code>Release()</code>, che implementano il [[conteggio dei riferimenti]] (''reference counting'') e controllano il ciclo di vita delle interfacce; e <code>QueryInterface()</code>, che specificando un ''IID'' permette al chiamante di ottenere riferimenti alle varie interfacce fornite dal componente.
ISomeInterface* pISomeInterface = NULL;
pISomeInterface = new CSomeObject();
</pre>
Materialmente, un'interfaccia consiste in un [[Puntatore (programmazione)|puntatore]] a una [[tabella di funzioni virtuali]] che contiene una lista di puntatori alle funzioni che implementano i metodi dichiarati nell'interfaccia, nello stesso ordine con cui sono dichiarati. Questa tecnica di passare liste di puntatori a funzione è l'evoluzione diretta di quella usata in [[Object Linking and Embedding|OLE 1.0]] per comunicare con le sue librerie di sistema.
In the first case, we are saying to the COM sub-system that we want to obtain a pointer to an object that implements the IMyObject interface and we want coclass CLSID_MyObject's particular implementation of this interface. In the second case, we are saying that we want to create an instance of a C++ class that implements the interface ISomeInterface and we are using CSomeObject as that C++ class.
COM specifica molte altre interfacce standard usate per la comunicazione tra componenti. Per esempio, una di queste interfacce è <code>IStream</code>, che è fornita dalle componenti che hanno [[semantica]] di flussi di dati (es. la componente <code>FileStream</code> usata per leggere e scrivere i file).
The equivalence should be clear. A coclass, then, is an object-oriented class in the COM world. The main feature of the coclass is that it is (1) binary in nature and consequently (2) programming language-independent.
Essa fornisce i metodi <code>Read</code> e <code>Write</code> per effettuare letture e scritture di flussi. Un'altra interfaccia standard è <code>IOleObject</code>, fornita dai componenti che prevedono di essere collegati o incapsulati dentro un contenitore. <code>IOleObject</code> contiene metodi che permettono ai chiamanti di determinare il rettangolo perimetrale della componente, determinare se la componente supporta operazioni come ''Apri'', ''Salva'', e così via.
-->
Come già detto, COM venne sviluppato avendo in mente il C++, quindi fa largo uso di puntatori. Questo rendeva impossibile l'uso di oggetti COM con linguaggi che non ne hanno, come il [[Visual Basic]], [[Java (linguaggio di programmazione)|Java]] e tutti i linguaggi di scripting; la '''OLE Automation''', fra le altre cose, pose rimedio a questa situazione. Le interfacce a puntatori vennero denominate ''custom interfaces'' e affiancate da nuove interfacce analoghe ma prive di puntatori, basate su array e collezioni di oggetti, denominate ''automation interfaces''; nella versione Automation, l'interfaccia IUnknown viene sostituita da '''IDispatch'''. Uno stesso componente può implementare le stesse interfacce in entrambe le versioni; tuttavia la versione Custom è obbligatoria, mentre la Automation è solo facoltativa.
===Registro di sistema===
In Windows, le classi COM, le interfacce e le librerie di tipi sono elencate per i rispettivi GUID nel [[registro di sistema]]; quando un'applicazione richiede il caricamento di una libreria, COM usa il registro per localizzarla, sia che si tratti di una libreria locale, sia che si tratti dell'indirizzo di rete di un servizio remoto.
===Conteggio dei riferimenti===
Il conteggio dei riferimenti (''[[reference counting]]'') viene usato dai componenti COM per sapere quando possono terminare e scaricarsi dalla RAM. Un programma client che utilizza il componente non può procedere con la sua eliminazione quando ha terminato di usarlo, perché potrebbe essere ancora in uso da altri programmi client (del resto in ambiente COM è prevista la possibilità che un client, una volta terminata l'interazione con un componente, passi il puntatore all'interfaccia dello stesso componente ad un altro client). Perciò l'eliminazione di un componente viene gestita da lui stesso attraverso il ''reference counting''; questa tecnica prevede che l'oggetto COM (ovvero il componente), quando passa il puntatore da una sua interfaccia ad un programma client (il che avviene in seguito alla richiesta da parte del client di poter utilizzare quella particolare interfaccia), incrementa di 1 il "reference count". Quando il client termina di utilizzare l'oggetto COM invoca il metodo '''IUnknown::Release()''' che decrementa di 1 il "reference count". Quando un client riceve il puntatore ad una interfaccia da un altro client invoca sull'oggetto COM il metodo '''IUnknown::AddRef()''' che incrementa di 1 lo stesso "reference count". L'oggetto COM si "auto-distruggerà" quando "reference count" è uguale a 0.
<!--
The COM specifications require a technique called [[reference counting]] to ensure that individual objects remain alive as long as there are clients which have acquired access to one or more of its interfaces and, conversely, that the same object is properly disposed of when all code that used the object have finished with it and no longer require it. Note that a COM object is responsible for freeing its own memory once its reference count drops to zero.
===Ereditarietà, contenimento e aggregazione===
The most fundamental COM interface of all, i.e. IUnknown (from which all COM interfaces must be based), supports the concept of reference counting by including the following two methods : '''AddRef()''' and '''Release()'''. Note well that when we speak of reference counting, we are actually referring to the reference count of a '''COM Object''', not the reference count of a '''COM Interface'''.
Lo standard prevede un meccanismo di ereditarietà ''singola'' che permette a un componente di estendere le funzioni di un altro: ogni interfaccia può ereditare i metodi di una (e solo una) interfaccia preesistente, ma non di modificare o di sostituire i metodi ereditati dall'interfaccia "padre".
Più in generale è prassi abbastanza comune per gli oggetti COM di una certa complessità fare uso di altri oggetti COM al loro interno; si parla di '''contenimento''' di un oggetto COM se il primo si avvale delle sue interfacce senza renderle disponibili al di fuori di esso, e di '''aggregazione''' se invece lo fa.
===RegFree COM===
A COM Object will internally maintain only one integer value that is used for reference counting. When AddRef() is called via the object's IUnknown or some other COM interface, this integer value gets incremented. When Release() is called, this integer gets decremented. AddRef() and Release() are the only means by which a client of a COM object is able to influence its lifetime. The internal integer value remains a private member of the COM object and will never be directly accessible.
[[Windows XP]] ha introdotto una nuova modalità di registrazione locale dei componenti COM, chiamata '''Registration-Free COM''' o RegFree COM per brevità. Con questa tecnica le applicazioni non devono più registrare metadati di attivazione e CLSID nel registro di Windows, ma possono specificarli nel loro '''manifest'''; questo può essere un file [[XML]] che risiede nella directory dell'applicazione stessa oppure essere contenuto nell'header del suo file eseguibile, come sezione in formato binario. Quando Windows caricherà l'applicazione e questa farà riferimento ai suoi oggetti COM, la class factory (l'ente che materialmente crea gli oggetti COM) consulterà il manifest dell'applicazione per cercare i GUID specificati e i metadati associati e caricherà quelli forniti con l'applicazione; solo se il manifest non contiene i GUID richiesti consulterà il registro di Windows e (se ne trova installati) creerà gli equivalenti oggetti COM di sistema.
Il limite di questa tecnologia è che non può essere usata con componenti COM che devono essere visibili in tutto il sistema, quindi non si può usare per server COM OutOfProcess o per implementare parti di sistema operativo ([[MDAC]], [[MSXML]], [[DirectX]] o [[Internet Explorer]]).
==Tecnologie correlate==
The purpose of AddRef() is to indicate to the COM object that an additional reference to itself has been effected and hence it is necessary to remain alive as long as this reference is still valid. Conversely, the purpose of Release() is to indicate to the COM object that a client (or a part of the client's code) has no further need for it and hence if this reference count has dropped to zero, it may be time to destroy itself.
COM è stata la principale piattaforma di sviluppo software per Windows e, in quanto tale, ha influenzato lo sviluppo di una serie di tecnologie a supporto.
===COM+===
Certain languages (e.g. Visual Basic) provides automatic reference counting so that COM object developers need not explicitly maintain any internal reference counter in their source codes. With other lower-level languages like C++, the declaration and use of an integer member in source code (used explicitly for reference counting) is necessary.
Con [[Windows 2000]], furono introdotte un numero significativo di estensioni COM chiamate '''COM+'''. Nello stesso periodo Microsoft de-enfatizzò [[Distributed Component Object Model|DCOM]] come entità separata.
===DCOM===
The following is a general guideline calling AddRef() and Release() to facilitate proper reference counting in COM object :
{{Vedi anche|Distributed Component Object Model}}
===.NET===
*Functions (whether object methods or global functions) that return interface references (via return value or via "out" parameter) should increment the reference count of the underlyling object before returning. Hence internally within the function or method, AddRef() is called on the interface reference (to be returned). An example of this is the QueryInterface() method of the IUnknown interface. Hence it is imperative that developers be aware that the returned interface reference has already been reference count incremented and not call AddRef() on the returned interface reference yet another time.
{{Vedi anche|Microsoft .NET}}
La piattaforma COM è stata ampiamente sorpassata da [[Microsoft .NET]], ed il marketing di Microsoft è del tutto incentrato su .NET; in un certo senso, COM adesso è addirittura [[deprecato]] a favore di .NET. Nonostante ciò, COM rimane una tecnologia importante per via della sua massiccia base software – per esempio, l'[[software development kit|SDK]] [[DirectX]] è basato su COM; inoltre, un componente COM è teoricamente sempre più prestante di un corrispondente componente gestito .NET{{citazione necessaria}}. Al momento della redazione di questa voce, Microsoft non ha annunciato di aver intenzione di ritirare né interrompere il supporto a COM.
Alcuni servizi che fornisce COM+, come le [[transazione (basi di dati)|transazioni]] e [[coda (informatica)|code di componenti]], sono ancora importanti per le applicazioni enterprise di .NET.
*Release() must be called on an interface reference when that interface reference is no longer required.
C'è un limite alla [[retrocompatibilità]]. Un oggetto COM può essere usato in .NET implementando un ''runtime callable wrapper'' (RCW).
*If a copy is made on an interface reference, AddRef() should be called on the interface reference. This is rather self-explanatory. After all, in this case, we are actually creating another reference on the underlying object.
==Sicurezza su Internet==
Even though the principles of reference counting may be simple, explicit reference counting maintenance in source codes is often error prone in practice especially for new COM developers. This can lead to incorrect reference count situations in which a COM object remains alive even when no client uses it, leading to memory leakage. The other (even more undesireable) situation is where a client makes a method call on a COM object which has already destroyed itself, leading to runtime errors.
Poiché le componenti COM e ActiveX sono eseguite come codice nativo sulla macchina dell'utente, ci sono poche restrizioni su ciò che il loro codice può fare. Molti di questi problemi sono stati affrontati dalla relativa deprecazione di COM nelle piattaforme sviluppate da allora, come la [[piattaforma Java]], e in seguito anche la [[Microsoft .NET|piattaforma .NET]].
L'idea della Microsoft di incapsulare il contenuto attivo nelle pagine web sotto forma di componenti COM/ActiveX (anziché, ad esempio, [[applet Java]]) ha creato una serie di problemi nel browser [[Internet Explorer]], che ha portato a un'esplosione di infezioni da [[Virus (informatica)|virus informatici]], [[trojan (informatica)|trojan]] e [[spyware]]. Questi attacchi di [[malware]] devono soprattutto a ActiveX la loro attivazione e propagazione agli altri computer. Microsoft ha riconosciuto il problema di ActiveX già nel [[1996]], quando [[Charles Fitzgerald]], direttore della squadra Java della Microsoft, ha detto "Se si vuole la sicurezza nella ''Rete'', si scolleghi il computer. (...) Non abbiamo mai sostenuto che ActiveX sia intrinsecamente sicuro."
To alleviate this highly problematic situation, Microsoft introduced '''ATL (Active Template Library)''' for C++ developers. ATL provides for a higher-level COM development paradigm. It also shields COM client application developers from the need to directly maintain reference counting by providing '''smart pointer objects'''.
-->
===Instanziamento===
<!--
COM standardizes the instantiation (i.e. creation) process of COM objects by requiring the use of '''Class Factories'''. In order for a COM object to be created, two associated items must exist :
* A Class ID.
* A Class Factory.
Each COM Object must be associated with a unique Class ID (a GUID). Each COM Object must also be associated with its own Class Factory. A Class Factory is itself a COM object. It is an object that must expose the IClassFactory interface. The responsibility of such an object is to create other objects.
A class factory object is usually contained within the same executable code (i.e. the '''server code''') as the COM object itself. The source codes of the class factory object may be written by the COM object developer himself/herself but it may also be emmited by a code generator program (e.g. the Visual Basic compiler). When a class factory is called upon to create a target object, this target object's class id must be provided. This is how the class factory knows which class of object to instantiate.
Take note that a single class factory object may create more than one class of objects. That is, two objects of different class ids may be created by the same class factory object. However, this is an internal detail which is of concern only to the COM object and class factory developer. It is transparent to the COM system.
Why do we need class factories ? By delegating the responsibility of object creation into a separate object, the developer is given greater flexibility in terms of object creation. For example '''singleton''' objects can be facilitated easily by a class factory.
In order that client applications are able to acquire class factory objects, COM servers must properly expose them. On this note, a class factory is exposed differently depending on the nature of the server code. A server which is DLL-based must export a '''DllGetClassObject()''' global function. A server which is EXE-based does not export any API. Rather, it registers the class factory at runtime via the '''CoRegisterClassObject()''' API.
The following is a general outline of the sequence of object creation via its class factory :
1. The object's class factory is obtained via the '''CoGetClassObject()''' API (a standard Windows API).
** As part of the call to CoGetClassObject(), the Class ID of the object (to be created) must be supplied. The following C++ code demonstrates this :
<pre>
IClassFactory* pIClassFactory = NULL;
CoGetClassObject
(
CLSID_SomeObject,
CLSCTX_ALL,
NULL,
IID_IClassFactory,
(LPVOID*)&pIClassFactory
);
</pre>
** The above code indicates that the Class Factory object of a COM object, which is identified by the class id CLSID_SomeObject, is required. This class factory object is returned by way of its IClassFactory interface.
2. The returned class factory object is then requested to create an instance of the originally intended COM object. The following C++ code demonstrates this :
<pre>
ISomeObject* pISomeObject = NULL;
if (pIClassFactory)
{
pIClassFactory -> CreateInstance
(
NULL,
IID_ISomeObject,
(LPVOID*)&pISomeObject
);
pIClassFactory -> Release();
pIClassFactory = NULL;
}
</pre>
** The above code indicates the use of the Class Factory object's '''CreateInstance()''' method to create an object which exposes an interface identified by the IID_ISomeObject GUID. A pointer to the ISomeObject interface of this object is returned. Also note that because the class factory object is itself a COM object, it needs to be released when it is no longer required (i.e. its '''Release()''' method must be called).
The above demonstrates, at the most basic level, the use of a class factory to instantiate an object. Higher level constructs are also available, some of which do not even involve direct use of the Windows APIs.
For example, the '''CoCreateInstance()''' API can be used by an application to directly create a COM object without acquiring the object's class factory. However, internaly, the CoCreateInstance() API itself will invoke the CoGetClassObject() API to obtain the object's class factory and then use the class factory's CreateInstance() method to create the COM object.
Visual Basic supplies the '''new''' keyword as well as the '''CreateObject()''' global function for object instantiation. These Visual Basic language constructs encapsulate the acquisition of the class factory object of the target object (via the CoGetClassObject() API) followed by the invokation of the IClassFactory::CreateInstance() method.
Other languages, e.g. PowerBuilder's PowerScript may also provide their own high-level object creation constructs. However, CoGetClassObject() and the IClassFactory interface remain the most fundamental object creation technique.
-->
===Riflessione===
<!--
Components can describe themselves using COM Type Libraries. A type library contains information such as the CLSID of a component, the IIDs of the interfaces the component implements, and descriptions of each of the methods of those interfaces. Type libraries are typically used by RAD environments such as [[Visual Basic]] or [[Visual Studio]] to assist in the programming of COM components.
-->
===Programmazione===
<!--
COM programmers are responsible for entering and leaving the COM environment, instantiating and reference counting COM objects, querying objects for version information, coding to take advantage of advanced object versions, and coding graceful degradation of function when newer versions aren't available.
-->
===Applicazioni e trasparenza della rete===
<!--
COM objects may be instantiated and referenced from within a process, across process boundaries within a computer, and across a network, using the DCOM technology. Out-of-process and remote objects may use [[marshalling]] to send method calls and return values back and forth. The marshalling is invisible to the object and the code using the object.
-->
===Thread in COM===
<!--
In COM, threading issues are addressed by a concept known as "'''apartment models'''". Here the term "'''apartment'''" refers to an execution context wherein a single thread or a group of threads is associated with one or more COM objects.
Apartments stipulate the following general guidelines for participating threads and objects:
*Each COM object is associated with one and only one apartment. This is decided at the time the object is created at runtime. After this initial setup, the object remains in that apartment throughout its lifetime.
*A COM thread (i.e., a thread in which COM objects are created or COM method calls are made) is also associated with an apartment. Like COM objects, the apartment with which a thread is associated is also decided at initialization time. Each COM thread also remains in their designated apartment until it terminates.
*Threads and objects which belong to the same apartment are said to follow the same thread access rules. Method calls which are made inside the same apartment are performed directly without any assistance from COM.
*Threads and objects from different apartments are said to play by different thread access rules. Method calls made across apartments are achieved via marshalling. This requires the use of proxies and stubs.
There are three types of Apartment Models in the COM world: '''Single-Threaded Apartment (STA)''', '''Multi-Threaded Apartment (MTA)''', and '''Neutral Apartment'''. Each apartment represents one mechanism whereby an object's internal state may be synchronized across multiple threads.
The Single-Threaded Apartment (STA) model is a very commonly used model. Here, a COM object stands in a position similar to a desktop application's user interface. In an STA model, a single thread is dedicated to drive an object's methods, i.e. a single thread is always used to execute the methods of the object. In such an arrangement, method calls are automatically queued by the system (via a standard Windows message queue) and there is no worry about race conditions or lack of synchronicity because each method call of an object is always executed to completion before another (even the same method) is invoked.
In case the COM object's methods perform their own synchronization, multiple threads dedicated to calling methods on the COM object are permitted. This is termed the Multiple Threaded Apartment (MTA). A process can consist of multiple COM objects, some of which may use STA and others of which may use MTA. The Thread Neutral Apartment allows different threads, none of which is necessarily dedicated to calling methods on the object, to make such calls. The only proviso is that all methods on the object must be serially reentrant.
-->
==Critiche==
===Inizializzazione dell'ambiente===
Per ogni [[Processo (informatica)|thread]] che necessita delle funzionalità di COM, il programmatore deve aggiungere chiamate esplicite alle funzioni <code>CoInitialize[Ex]</code> e <code>CoUninitialize</code>; inoltre, il codice utilizzanteche utilizza gli appunti o il drag & drop OLE deve chiamare <code>OleInitialize</code> e <code>OleUninitialize</code>. Dato che alcuni thread nel sistema possono essere stati creati da librerie che non usano COM, il programmatore deve prestare attenzione nell'usare qualsiasi funzione di COM in un thread che non è stato creato all'interno del programma stesso.
===Smistamento dei messaggi===
Quando un ''Single-Threaded Apartment'' viene inizializzato, crea una finestra nascosta che viene utilizzata per l'indirizzamento dei messaggi ''inter-apartment'' e ''inter-process''. Questa finestra deve avere la sua procedura standard per la gestione dei messaggi. Questo procedimento è noto come smistamento dei messaggi (message pump). Nelle versioni precedenti di Windows, un errore nel fare questo poteva causare un blocco a livello di sistema. Questo problema è ulteriormente complicato da alcune [[Application programming interface|API]] di Windows che inizializzano COM come parte della loro implementazione, che causa a sua volta una mancanza di dettagli dell'implementazione del componente COM.
<!--
When COM is initialized it creates a hidden window that is used for inter-thread and inter-process message routing. This window must have its message queue regularly pumped. On earlier versions of Windows failure to do so could cause system-wide deadlock. This problem is especially nasty because some Windows APIs initialize COM as part of their implementation, which causes a leak of implementation details.
-->
===Conteggio dei riferimenti===
Uno scenario in cui il reference counting porta a problemi è quello in cui due oggetti COM si riferiscono l'un l'altro, come accade ad esempio usando i ''''connection points'''' o gli ''''event sink''''. In questo caso nessuno dei due oggetti può rilasciare se stesso perché deve prima rilasciare l'altro, che dal canto suo non può farsi rilasciare perché ha ancora un riferimento all'oggetto che vorrebbe rilasciarlo. Questo circolo vizioso si può spezzare in due modi: una terminazione forzata (out-of-band termination) di uno dei due oggetti, oppure la creazione di due oggetti COM identici referenziati debolmente, di cui uno è usato per connettersi al partner di comunicazione e l'altro serve solo per terminare il primo.
<!--
Reference counting within COM may cause problems if two or more objects are [[circular reference|circularly referenced]]. The design of an application must take this into account so that objects are not left orphaned.
Objects may also be left with active reference counts if the COM "event sink" model is used. Since the object that fires the event needs a reference to the object reacting to the event, the objects reference count will never reach zero.
Reference cycles are typically broken using either out-of-band termination or split identities. In the out of band termination technique, an object exposes a method which, when called, forces it to drop its references to other objects, thereby breaking the cycle. In the split identity technique, a single implementation exposes two separate COM objects (also known as identities). This creates a [[weak reference]] between the COM objects, preventing a reference cycle.
-->
===Inferno delle DLL===
Ogni interfaccia COM è anche un contratto fra chiamante e chiamato: un programma che usa un componente COM deve assumere che i metodi che chiama si comporteranno sempre come previsto e non ha alcun controllo su di essi. Dal momento che la posizione di ogni componente è memorizzata in un luogo di livello sistema (ilin Windows nel [[registro di sistema]]), solamente una versione dello stesso componente può essere installata nel sistema in un dato momento, tipicamente la versione che l'ultima applicazione installata ha portato con sé; ase causail dinuovo ciòcomponente ha proprietà anche solo leggermente diverse da quello precedente, COMle risentealtre pesantementeapplicazioni genereranno improvvisamente errori e comportamenti imprevedibili o casuali, senza alcun motivo apparente. Questo fenomeno è delchiamato "[[Dynamic-link library|DLL]] hell" (''"Inferno delle DLL"''), situazione intristemente cuinota duea oprogrammatori piùe applicazioniamministratori richiedonodi versionisistema. differentiCon dellola stesso{{Chiarire|RegFree componenteCOM}} di Windows XP questo grave inconveniente può essere drasticamente ridotto.
==RiferimentiNote==
<references />
<!--
*{{cite web | title=COM: A Brief Introduction | url=http://www.cs.ucr.edu/~dberger/Documents/Presentations/com-intro.ppt | accessdate=March 7 | accessyear=2006 }}
-->
== Voci correlate ==
==Argomenti correlati==
*[[CAPICOM]]
*[[Distributed Component Object Model|Distributed Component Object Model (DCOM)]]
*[[Distributed Component Object Model]]
*[[Dynamic Data Exchange|Dynamic Data Exchange (DDE)]]
*[[Dynamic Data Exchange]]
*[[Microsoft .NET]]
*[[Object Linking and Embedding|Object Linking and Embedding (OLE)]]
*[[OLE for Process Control]]
==Collegamenti esterni==
*{{en}} [https://web.archive.org/web/20041011222635/http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_aboutole.asp What OLE is Really About] by Kraig Brockschmidt. An Overview of COM and OLE.
*{{en}} [http://www.microsoft.com/com/ Microsoft COM Technologies]
*{{cita web|http://www.research.microsoft.com/comapps/|Component Application Group at Microsoft Research|lingua=en}}
*{{en}} [http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_aboutole.asp What OLE is Really About] by Kraig Brockschmidt. An Overview of COM and OLE.
*{{cita web|1=http://www.iol.ie/~locka/mozilla/mozilla.htm|2=Mozilla ActiveX Project|lingua=en|accesso=2 maggio 2006|urlarchivio=https://web.archive.org/web/20060721123224/http://www.iol.ie/%7Elocka/mozilla/mozilla.htm|dataarchivio=21 luglio 2006|urlmorto=sì}}
*{{en}} [http://www.research.microsoft.com/comapps/ Component Application Group at Microsoft Research]
*{{en}} [https://web.archive.org/web/20060428072429/http://www.codeproject.com/com/comintro.asp Introduction To Com] - basic introduction on how to use COM-components, CodeProject
*{{en}} [http://www.iol.ie/~locka/mozilla/mozilla.htm Mozilla ActiveX Project]
*{{en}} [https://support.microsoft.com/kb/159621/en-us INFO: Difference Between OLE Controls and ActiveX Controls] from Microsoft
*{{en}} [http://www.codeproject.com/com/comintro.asp Introduction To Com] - basic introduction on how to use COM-components, CodeProject
*{{cita web|1=http://www.codeproject.com/com/CCOMThread.asp|2=Understanding The COM Single-Threaded Apartment Part 1|lingua=en|accesso=2 maggio 2006|urlarchivio=https://web.archive.org/web/20060719003112/http://www.codeproject.com/com/CCOMThread.asp|dataarchivio=19 luglio 2006|urlmorto=sì}}
*{{en}} [http://support.microsoft.com/kb/159621/en-us INFO: Difference Between OLE Controls and ActiveX Controls] from Microsoft
*{{en}}cita [web|1=http://www.codeproject.com/com/CCOMThreadCCOMThread2.asp |2=Understanding The COM Single-Threaded Apartment Part 1]2|lingua=en|accesso=2 maggio 2006|urlarchivio=https://web.archive.org/web/20060614231735/http://www.codeproject.com/com/CCOMThread2.asp|dataarchivio=14 giugno 2006|urlmorto=sì}}
*{{cita web|1=http://www.codeproject.com/useritems/BuildCOMServersInDotNet.asp|2=Building COM Servers in .NET|lingua=en|accesso=2 maggio 2006|urlarchivio=https://web.archive.org/web/20060717235730/http://www.codeproject.com/useritems/BuildCOMServersInDotNet.asp|dataarchivio=17 luglio 2006|urlmorto=sì}}
*{{en}} [http://www.codeproject.com/com/CCOMThread2.asp Understanding The COM Single-Threaded Apartment Part 2]
*{{en}} [http://www.codeproject.com/useritems/BuildCOMServersInDotNet.asp Building COM Servers in .NET]
{{Componenti di Windows}}
[[Categoria:Sistema operativo]]
{{Controllo di autorità}}
{{portale|informatica|microsoft}}
[[Categoria:Software di sistema]]
[[Categoria:Linguaggi di programmazione]]
[[Categoria:Microsoft]]
[[de:Component Object Model]]
[[en:Component Object Model]]
[[es:Component object model]]
[[fi:ActiveX]]
[[fr:Component Object Model]]
[[hu:Component Object Model]]
[[ja:Component Object Model]]
[[pl:COM]]
[[pt:ActiveX]]
[[ru:COM]]
[[sv:Component Object Model]]
[[zh:组件对象模型]]
|