I have two .exe application. Each of them contains interfaces compatible with Automation and described in projects IDLs. So, I have tlb for both applications. Need to organize the call methods of the class that implements one of the interfaces from code running in another/different application. Just how it works in COM Server and COM client throw out-of-process boundary. But intrefaces is privacy and not registered in Registry, so standard CoMarshalInterface/CoUnmarshalInterface is not working.
How I can do it, manualy organize marshaling (all requred data are exist: tlb, automation compatible interfaces) ?
P.S. Looks like this but without registry registration.
Having type library available and registered you might expect COM to create proxy/stub pairs automatically using type library information. This is however not the only way, COM will first query the object if it is capable to marshhal itself into stream, via IMarshal interface, IMarshal::MarshalInterface method.
Marshaling Details on MSDN writes:
Custom marshaling is inherently unique to the object that implements
it. It uses proxies implemented by the object and provided to the
system on request at run time. Objects that implement custom
marshaling must implement the IMarshal interface, whereas objects that
support standard marshaling do not.
By implementing custom marhshaling this way you have your COM object saving its essential information into stream, and it provides CLSID of unmarshaler to re-create the interface on the other side. The data will be passed over process boundary and your object will be instantiated and provided this stream data in order for you to re-create the interface in question.
Hence, implement IMarshal and friends and you will be able to integrate into COM processing without having your type library registered or even available.
To communicate two process containing COM objects, you can use ROT (Running object table), here's a sample showing how to do it.
Related
I am using out-of-process COM object that is hosted by myexe.exe. There are multiple versions of those exes which host the COM object. Each version can have slightly changed interfaces and methods. Each of myexe.exe files are located in versioned folders(e.g. C:\v2\myexe.exe, c:\v3\myexe.exe)
There is no way to know ahead of time which of the versions will be running. My client application attaches to the running exes using ROT. I need to be able to use that COM object version dynamically, discovering interfaces through IUnknown.QueryInterface.
Unfortunately I am getting crash when using newer methods if older version of COM is registered in Windows Registry. Once I register newer version of out-of-proces COM in windows registry using "myexe.exe -regserver" the crash goes away. So i cannot dynamically use older or newer version of meexe.exe at runtime as each time i need to re-register my com version.
Any ideas on why i get the crash or how to solve the problem?
COM interfaces are never versioned. Each COM interface is as different as any other.
You use IIDs to differentiate and go from one to another using QueryInterface().
See QueryInterface guidelines and the Guide.
COM interfaces are immutable. Once you have defined an interface and start using it in your apps, you CAN'T change it anymore. Its IID and VTABLE are locked in. If you need to make changes to existing methods, or add new methods, you MUST create a new interface with a new IID for that purpose (the new interface can derive from the previous interface, though that is not required). The server must then implement the new interface, and clients can QueryInterface() the server for the new interface when needed. There is no getting around this, it is a fundamental rule of COM, so as not to break existing clients when creating new server versions.
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!
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.
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):
IUnknownStandard virtual method invocation. Fast, no extra code. Requires compile time interface information (.h or .tlb) on the client calls
IDispatch"Late Binding". Slow, lots of interpreting code. No client compilation or interface spec needed.
Practically speaking, unless you are calling from VBA, VBScript or have some old VB6 clients then you are better off sticking with IUnknown exclusively.
Creating an ATL project in MSVC seems to create not one but two projects; the latter named the same as the former but with PS appended to its name. What is the purpose of this second project and how can I tell whether I need it?
COM supports making interface method calls across two different threads, two different processes or two different machines. This is called marshaling. Two different threads is the most common case, a COM server is often not thread-safe. COM implements thread-safety for such single-threaded coclasses by marshaling the call from the 'wrong' thread to the thread that created the server. Marshaling between processes occurs when you write an out-of-process server. Between different machines across a network is called DCOM.
This is implemented by creating an instance of the interface that looks exactly like the original. But all the methods of the interface are actually substitutes that do the job of the marshaling the call. This is the proxy. On the other end of the wire there's a substitute that looks exactly like the interface but does the opposite job. This is the stub. The proxy and stub work together to create the illusion that you're making a simple method call in your program.
The primary job of the proxy is to serialize the arguments of the method call into a memory buffer or network packet. This can be pretty untrivial, especially when you use pointers to variable-sized structures. COM needs help to get that right and that's the job of your FooPS project. When you run midl.exe on your .idl file, midl auto-generates code from the interface definitions to implement the proxy and the stub. This is quite often good enough but you may need to implement your own if the built-in keywords in IDL are not sufficient to describe your data.
Last but not least, Windows provides a standard marshaller that can marshal simple interfaces. Designed to support the sub-set of COM that's defined by COM Automation. In other words, interfaces that derive from IDispatch and only use Automation compatible types. You only need to get the registry entries right to enable it and don't otherwise need the proxy/stub generated by midl. And of course, if you only make simple in-process calls on one thread then you won't need it either. This is pretty common.
As #ebutusov said, *PS project contains implementations for Proxy and Stub. They are not standard, instead they are generated by MIDL for interfaces exported from your ATL server. These interfaces are declared in the *.IDL file. The ouput of the project is DLL. You may read this article to get more details.
You may remove PS project from the solution in case if you do not define any custom interfaces in you *.IDL file or if you define only interfaces which have dual and oleautomation modifiers. In that case a standard typelib marshaller will be used.
In order to be able to make use of the standard typelib marshaller, one has to register a typelibrary (which is done automatically since you are using ATL)
It's proxy/stub code, which contains non-standard data marshallers needed to transfer data between different apartments (threading related). It's used when application, which calls your COM object, uses different COM threading model. There was an option in ATL/COM wizard to merge this code into main library. In many common scenarios you don't have to worry about it (i.e. when your COM dll runs in the client context), unless you want to write a custom marshaller.
I have a VB6 COM DLL. I want to use it from C++. I know how to register it, generate a tlb file from the DLL, and #import it in C++.
I'd like however, to load and use DLLs like this dynamically, at runtime, without knowing them in advance. Is this possible?
Thanks,
Yes, but you need to get the question clearer.
Sometimes, you do know the COM interface upfront, just not the implementation. In that case, you can create a dummy implementation of the interface and #import that. At runtime, you'd still register the real component, get an object from it (via CoCreateInstance probably) and store that in an appropriate smart pointer.
With VB6, it's a bit less direct. This adds a level of indirection. Read up on IDispatch. You need to get that known interface to describe an unknown interface. That way, the unknown interface can be obtained at runtime.
IMHO, You need at least some common interface (so you known what to call in the C++ side).
I'd do something like:
Define a common interface (in its own DLL/TLB)
Implement this interface in one or more COM servers
Import this interface in the C++ side (let's call it client)
Define a way to pass the progid of the COM server you want to work with (load dynamically) in the client.
Hope this helps
Take a look at these two MSDN articles about Registration-Free Activation of COM Components:
Registration-Free Activation of COM Components: A Walkthrough
Escape DLL Hell: Simplify App Deployment with ClickOnce and Registration-Free COM
There also have been some similar question here on StackOverflow:
Generate manifest files for registration-free COM
Windows/C++: how to use a COM dll which is not registered
I've seen with Microsoft COM and XPCOM, at least from what I've read and gathered so far, that the implementations of interfaces in a component have to essentially be in the single class that derives all the virtual interfaces. Is this correct? What am I missing?
Is there a way to have multiple objects (possibly in separate DLL's) each provide their functionality and still be able to freely transition between them using QueryIterface?
What I'm looking for is to have a component with some functionality, but still allow external client code to create new extensions of the component with (possibly) new interfaces. Ideally this should happen without divulging the current source of the component and its implementation.
This should be possible, although probably not supported by the standard high-level wrappers. Most of the wrappers (ATL, MFC, etc.) only support mapping a COM object to a single class. However, QueryInterface is allowed to return a different pointer and calls COM object code, so the first COM object could load a different DLL, instantiate a different object, and return a pointer to it's interface (vtable).
It's all possible as far as I know, you'll just likely be writing a lot of the low-level glue code yourself.
Yes, ATL supports tear-off interfaces
This allows to imlement the interface in another class that is instantiated only when the interface is requested. Since it passes only an interface, I guess it can be put into a separate DLL, too.
(can also be cached after being requested once)