Reputation: 1
I would like to understand the purposes of the files mentioned in this article and link the knowledge to my current COM server and COM client scenario, so that I can implement my COM server to use the COM server: this
I am having a COM server which is an exe, or service, that runs in the background. For now, I know there is an exposed interface inherited both from IUnknown and IDispatch. Besides I have the following files generated:
xxx_i.c defines all the CLSIDs and IIDs
xxx_i.h defines all the method the interface supports
xxx_p.c ?
dlldata.c ?
I am now using the automation way, IDispatch -> Invoke(), to access the interface methods. Although this way seems work fine without using any files mentioned above, I still would like to understand the purposes of them while using the normal way, IUnknown -> QueryInterface(), to access the methods.
Since I am new to the COM world, any suggested reading would be appreciated! Thanks!
Upvotes: 0
Views: 250
Reputation: 138960
In its most simple form, COM is only the vtable
binary contract plus the mother of all interfaces: IUnknown
. COM is a way to reuse code without source, with components, it's some kind of a dynamic casting mechanism. Provided I know the coclasses you support (their CLSID
), the interfaces they expose (their IID
), and what are these interfaces' methods layout, their parameters, order, type, etc., I can use your COM server.
But to ease "communication" between your COM clients and your COM server, you can/should use some standard mechanisms/documentation and add tooling so plumbing stuff like marshaling (=serialization) will be taken care w/o any effort. This is crucial in the out-of-process case, less important with in-process (I will elude the "apartment" concept here...)
So, lots of things you'll find in COM (like registration, tooling, IDL, typelibs, etc.) are in fact optional, but also very useful (so they kinda become mandatory in the end). The purpose of things like idl
(for "interface language definition") is to define and expose to your COM clients what your COM server supports so tooling can generate a lot of code automatically for you and your clients (.c, .h, .tlb). Note that nothing prevents you from implementing interfaces or coclasses without defining them in idl. Nothing obliges you to provide your .idl or your .tlb. In this case, I will only be able to use them if I known their IID, method layout etc.
Then, on top of IUnknown
, Microsoft created a universal interface called IDispatch
(this is also known as "Automation", or "Late binding" as opposed to "Early binding" for IUnknown
), at that time targeting VB/VBA clients (before even VBScript, JScript, and lots of other COM clients, .NET supports IUnknown and IDispatch). IDispatch
, if you go that route, could be the last interface you'll ever have to implement, because its semantics allows full discovery and invocation of any method, provided it supports a finite set of defined data types, the "Automation types": BSTR, VARIANT, etc.
So, if you support IDispatch
, provide a TLB (typelibs) and restrict all types to Automation types, then you don't need to handle marshaling, you don't need proxies and stubs, you can forget about all this, even in out-of-process scenarios, because Microsoft implements that automatically. Back in the days, we used to call "oleaut32.dll" the "universal marshaler".
Dual interfaces are interfaces that support both IUnknown
and derivates and IDispatch
at the same time. They mostly exist to support C/C++ clients and Automation clients at the same time. Using Automation (BSTR, VARIANT, etc.) is a bit painful in C/C++ because they were not intended originally to be used by C/C++ clients... Note Microsoft proposes C++ smart wrappers classes: CComBSTR
and CComVARIANT
with ATL, or _variant_t
and _bstr_t
with the Windows SDK.
Upvotes: 1
Reputation: 22271
Requests for reading material are out of scope for StackOverflow, but I can't help but to reccomend the seminal work by Don Box: Essential COM which is in print and available as an ebook elsewhere. Here's Don's description of the topic:
Box, Don. Essential COM. Addison-Wesley, 1998, pp. 350:
COM is based on client programs having a priori knowledge of an interface's definition at development time. This is accomplished either through C++ header files (for C++ clients) or through type libraries (for Java and Visual Basic clients). In general, this is not a problem, as programs written in these languages typically go through some sort of compilation phase prior to being deployed. Some languages do not go through such a compilation phase at development time and instead are deployed in source code form to be interpreted at runtime.
Perhaps the most pervasive of such languages are HTML based scripting languages (e.g., Visual Basic Script, JavaScript) that execute in the context of either a Web browser or a Web server. In both of these cases, script text is stored in its raw form embedded in an HTML file, and the surrounding runtime executes the script text on the fly as the HTML is parsed. To provide a rich programming environment, these environments allow scripts to invoke methods on COM objects that may be created in the script text itself or perhaps elsewhere in the HTML stream (e.g., a control that is also part of the Web page). In these environments, it is currently impossible to use type libraries or other a priori means to provide the runtime engine with a description of the interfaces being used. This means that the objects themselves must assist the interpreter in translating the raw script text into meaningful method invocations.
To allow objects to be used from interpretive environments such as Visual Basic Script and JavaScript, COM defines an interface that expresses the functionality of interpretation.
Tl;dr: there are two ways to do everything in COM (ignoring IInspectable
and dual interfaces):
IUnknown
IDispatch
Practically speaking, unless you are calling from VBA, VBScript or have some old VB6 clients then you are better off sticking with IUnknown
exclusively.
Upvotes: 0