what are the things to note while adding a new interface in C++ COM (ATL) - c++

I have added a new interface IAEx which is extended from the existing interface IA (derived from IDispatch).
What are the things to change in idl?
I have changed the coclass definitions to inherit from the new one.
I changed the coclass entry in idl which was like this earlier.
(I need the deafult interface as new one)
coclass CAx
{
[default] interface IA
[default, source] dispinterface IAEvents;
};
and changed to
coclass CAx
{
[default] interface IAEx
[default, source] dispinterface IAEvents;
};
can I change the deafualt interafce?
coclass definition change.
old one
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IA, &IID_IA, &LIBID_CCALib>,
new one.
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IAEx, &IID_IAEx, &LIBID_CCALib>,
Is this fine?
COM MAP entries modification:
Old one:
COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch,IA)
new one:
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY2(IDispatch,IAEx)
Do I need to add old interface also in COM MAP?

No, this is a drastically breaking change to client programs. Golden rule #1 to keep in mind is that names are quite immaterial in COM, only uuids matter. Rule #2 is that COM components have machine scope, modifying a component affects every program on the machine that uses the component. Another way to say that is that COM has a strong DLL Hell problem.
So the first thing that will happens when you install your component on a machine is that every program that uses it will stop to work. They are still looking for the "IA" interface uuid and it is not there anymore. They fail with E_NOINTERFACE. Only way to avoid that is to get the client programs recompiled with your new type library and deploy them at the exact same time your updated COM component is deployed. This is often very hard to arrange since they don't have programmers or companies in common. Usually only the user can do this, they very rarely know how to do this correctly or know how to troubleshoot failure.
If you want your update to be backwards compatible then you must add a new interface to your coclass. It cannot be the [default] interface since existing client programs expect the legacy interface as the default. That however causes a new problem, client runtimes that use IDispatch often don't support anything but a single default interface. Usually because they don't have a notion of interfaces as a primary language construct. In other words, your client programmer has no way to call IUnknown::QueryInterface() and therefore cannot use your new interface at all. So not a general solution.
It is technically possible to violate the interfaces are immutable rule in COM. You can add new methods to the end of the IDispatch interface. Existing client code is unaware of them so will never call them and continue to operate correctly both with the old and the new version of your component. Assuming that you know how to maintain the legacy methods without causing a breaking behavior change, often harder than it looks. There is still a DLL Hell problem though, the world implodes when an updated version of the client code meets the old version of your component. This might seem unlikely at first sight but this tends to go wrong much later, when the machine is replaced or re-imaged. Very ugly scenario, the runtime failure is impossible to diagnose and anybody originally involved is not around anymore or doesn't remember the details.
Only truly safe way to do this is to create a new version. Modify all the uuids (LIBID, CLSID and IID) and change the DLL filename. Now the old and new version can co-exist and the client programmer can use your new version at his leisure. There might still be a deployment problem but the failure is easy to diagnose, the client program fails with "Class not registered".

You should include the old interface in the COM MAP as well as if a client attempts to QueryInterface for the old interface it should receive a useful result and not an error. Add COM_INTERFACE_ENTRY2(IA, IAEx).
Otherwise it looks like you have everything. We add both interfaces into the coclass entry in the IDL file but I don't thing anything really uses that. ie:
coclass Ax
{
[default] interface IAEx;
interface IA;
};

Whether it is fine or not depends on what is the goal exactly. Replacing interface is fine on its own, if you are concerned with not breaking compatibility with existing client, the most important thing is that your server still implements old interface IA. You should list the interface on the COM MAP (since you mentioned that IAEx is inherited from IA, you might need a COM_INTERFACE_ENTRY_IID macro):
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY_IID(__uuidof(IA), IAEx) //COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch, IAEx)
This way your server implements both IAEx and IA. Inheriting interfaces one from another is the thing I would rather suggest against, but you have what you have.
Updating coclass (as suggested in answer by patthoyts) makes update cleaner and is worth doing as well, however it is more important for rebuilding the clients rather than keeping compatibility with already existing built code: tools importing type library information will be able to see both interfaces if they at all care and are capable to handle non-default interfaces there.

Related

Query related to VB script and COM interface inheritance

i have a legacy COM components, as part of upgradation i derived from an existing interface
interface1
{
few methods
}
interface2 :public interface1
{
new methods
}
there was an old review comment not to do this..instead have inteface2 has separate one not deriving from the base, as it part of the same CoClass...there is no need to duplicate any code...
review comment :
Scripting languages are interpreted languages and are naturally polymorphic as all methods are late bound. All variables are typeless (VARIANT is typeless).
However, there is a separate problem concerning scripting languages. Scripting languages do not use the virtual function table in order to invoke methods on a COM object but instead invoke methods via the IDispatch interface. Unfortunately IDispatch can only be associated with one custom interface.
All methods accessed via IDispatch must be part of the custom interface
can anyone explain ...does he mean to say that getidsofnames will not be able to return the correct ID ? or is it something else
It is accurate enough, a coclass can implement multiple interfaces. But one is "special", it is the one that's attributed with [default] in the IDL. Scripting languages can only use that default interface, they don't have a mechanism to retrieve another interface. Or in other words, they can't call QueryInterface(). Mostly because they don't support the notion of interfaces or casting or multiple inheritance at all in their language design. Intentionally, scripting languages are supposed to be easy to use.
So if interface1 was originally the default interface then the scripting programmer can never use the added interface2 methods. You'll want to have a look at this SO post to see the consequences.
You can keep COM interfaces backwards compatible with old client programs by only ever appending new methods and never change the order or arguments of the old ones. It is risky, an updated client program that accidentally meets an old version of your component will go up in flames in a very bad way. Usually very hard to diagnose, pure DLL Hell. Only truly safe way is to assign new [uuid]s, forcing the client program to be recompiled. If you also change the name or install location of the DLL then they can live side-by-side.

Runtime interfaces and object composition in C++

I am searching for a simple, light-weight solution for interface-based runtime object composition in C++. I want to be able to specify interfaces (methods declarations), and objects (creatable through factory pattern) implementing these. At runtime I want mechanisms to instantiate these objects and interconnect these based on interface-connectors. The method calls at runtime should remain fairly cheap, i.e. only several more instructions per call, comparable to functor patterns.
The whole thing needs to be platform independent (at least MS Windows and Linux). And the solution needs to be licensed liberally, like open source LGPL or (even better) BSD or something, especially allowing use commercial products.
What I do not want are heavy things like networking, inter-process-communication, extra compiler steps (one-time code generation is ok though), or dependencies to some heavy libraries (like Qt).
The concrete scenario is: I have such a mechanism in a larger software, but the mechanism is not very well implemented. Interfaces are realized by base classes exported by Dlls. These Dlls also export factory functions to instantiate the implementing objects, based on hand-written class ids.
Before I now start to redesign and implement something better myself, I want to know if there is something out there which would be even better.
Edit: The solution also needs to support multi-threading environments. Additionally, as everything will happen inside the same process, I do not need data serialization mechanisms of any kind.
Edit: I know how such mechanisms work, and I know that several teaching books contain corresponding examples. I do not want to write it myself. The aim of my question is: Is there some sort of "industry standard" lib for this? It is a small problem (within a single process) and I am really only searching for a small solution.
Edit: I got the suggestion to add a pseudo-code example of what I really want to do. So here it is:
Somewhere I want to define interfaces. I do not care if it's C-Headers or some language and code generation.
class interface1 {
public:
virtual void do_stuff(void) = 0;
};
class interface2 {
public:
virtual void do_more_stuff(void) = 0;
};
Then I want to provide (multiple) implementations. These may even be placed in Dll-based plugins. Especially, these two classes my be implemented in two different Dlls not knowing each other at compile time.
class A : public interface1 {
public:
virtual void do_stuff(void) {
// I even need to call further interfaces here
// This call should, however, not require anything heavy, like data serialization or something.
this->con->do_more_stuff();
}
// Interface connectors of some kind. Here I use something like a template
some_connector<interface2> con;
};
class B : public interface2 {
public:
virtual void do_more_stuff() {
// finally doing some stuff
}
};
Finally, I may application main code I want to be able to compose my application logic at runtime (e.g. based on user input):
void main(void) {
// first I create my objects through a factory
some_object a = some_factory::create(some_guid<A>);
some_object b = some_factory::create(some_guid<B>);
// Then I want to connect the interface-connector 'con' of object 'a' to the instance of object 'b'
some_thing::connect(a, some_guid<A::con>, b);
// finally I want to call an interface-method.
interface1 *ia = a.some_cast<interface1>();
ia->do_stuff();
}
I am perfectly able to write such a solution myself (including all pitfalls). What I am searching for is a solution (e.g. a library) which is used and maintained by a wide user base.
While not widely used, I wrote a library several years ago that does this.
You can see it on GitHub zen-core library, and it's also available on Google Code
The GitHub version only contains the core libraries, which is really all the you need. The Google Code version contains a LOT of extra libraries, primarily for game development, but it does provide a lot of good examples on how to use it.
The implementation was inspired by Eclipse's plugin system, using a plugin.xml file that indicates a list of available plugins, and a config.xml file that indicates which plugins you would like to load. I'd also like to change it so that it doesn't depend on libxml2 and allow you to be able to specify plugins using other methods.
The documentation has been destroyed thanks to some hackers, but if you think this would be useful then I can write enough documentation to get you started.
A co-worker gave me two further tips:
The loki library (originating from the modern c++ book):
http://loki-lib.sourceforge.net/
A boost-like library:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/
I still have not looked at all the ideas I got.

Why does Microsoft have IHTMLDocument, IHTMLDocument2, ... , IHTMLDocument8?

What is the meaning of the number in the end of the interface name? I see that IHTMLDocument3-7 have no members (see example for #5), and 8 has gesture related members. Is the number derived from Windows version?
This is a general feature of public COM interfaces.
If you want backward compatibility, you never want to change a published interface, because that would mean all the code people wrote for, say, IE 6 stops working with IE 7, and all of their customers get mad at them, and they get mad at you.
So, if IE 5 adds new features that needed to be exposed, instead of changing IHTMLDocument, you create a new interface, and make IE5 support both (by inheritance, QueryInterface, or some more explicit mechanism). And when IE 7.0.2 or IE 8 or Win XP or whatever adds even more new features, you create another one. And so on.
While MS could have come up with descriptive suffixes instead of just sequential numbers, that would probably be more confusing than helpful. So, IHTMLDocument2, IHTMLDocument3, etc. are the names. They don't mean anything, except the order they were added.
What is the meaning of the number in the end of the interface name?
That is the standard convention for versioning COM interfaces. IXXX2 extends IXXX with new functions. IXXX3 extends IXXX2 with new functions, and so on. This allows clients to use older functions without breaking when new versions are released, and use newer functions when desired, even check if those functions are available before trying to call them.
I see that IHTMLDocument3-7 have no members
Where did you get that idea from? Look at their actual definitions. They expose many new members from one interface to the next.
No - it just signifies a different version of the interface. It has nothing to do with Windows version (and, for that matter, little/nothing to do with MSHTML version):
http://msdn.microsoft.com/en-us/library/aa752641%28v=vs.85%29.aspx
as of http://msdn.microsoft.com/en-us/library/aa752541(v=vs.85).aspx
where we can see :
The IHTMLDocument3 interface inherits from the IDispatch
interface but does not have additional members.
it can bee little confusing for newcomers to interface world.

Module and classes handling (dynamic linking)

Run into a bit of an issue, and I'm looking for the best solution concept/theory.
I have a system that needs to use objects. Each object that the system uses has a known interface, likely implemented as an abstract class. The interfaces are known at build time, and will not change. The exact implementation to be used will vary and I have no idea ahead of time what module will be providing it. The only guarantee is that they will provide the interface. The class name and module (DLL) come from a config file or may be changed programmatically.
Now, I have all that set up at the moment using a relatively simple system, set up something like so (rewritten pseudo-code, just to show the basics):
struct ClassID
{
Module * module;
int number;
};
class Module
{
HMODULE module;
function<void * (int)> * createfunc;
static Module * Load(String filename);
IObject * CreateClass(int number)
{
return createfunc(number);
}
};
class ModuleManager
{
bool LoadModule(String filename);
IObject * CreateClass(String classname)
{
ClassID class = AvailableClasses.find(classname);
return class.module->CreateObject(class.number);
}
vector<Module*> LoadedModules;
map<String, ClassID> AvailableClasses;
};
Modules have a few exported functions to give the number of classes they provide and the names/IDs of those, which are then stored. All classes derive from IObject, which has a virtual destructor, stores the source module and has some methods to get the class' ID, what interface it implements and such.
The only issue with this is each module has to be manually loaded somewhere (listed in the config file, at the moment). I would like to avoid doing this explicitly (outside of the ModuleManager, inside that I'm not really concerned as to how it's implemented).
I would like to have a similar system without having to handle loading the modules, just create an object and (once it's all set up) it magically appears.
I believe this is similar to what COM is intended to do, in some ways. I looked into the COM system briefly, but it appears to be overkill beyond belief. I only need the classes known within my system and don't need all the other features it handles, just implementations of interfaces coming from somewhere.
My other idea is to use the registry and keep a key with all the known/registered classes and their source modules and numbers, so I can just look them up and it will appear that Manager::CreateClass finds and makes the object magically. This seems like a viable solution, but I'm not sure if it's optimal or if I'm reinventing something.
So, after all that, my question is: How to handle this? Is there an existing technology, if not, how best to set it up myself? Are there any gotchas that I should be looking out for?
COM very likely is what you want. It is very broad but you don't need to use all the functionality. For example, you don't need to require participants to register GUIDs, you can define your own mechanism for creating instances of interfaces. There are a number of templates and other mechanisms to make it easy to create COM interfaces. What's more, since it is a standard, it is easy to document the requirements.
One very important thing to bear in mind is that importing/exporting C++ objects requires all participants to be using the same compiler. If you think that ever could be a problem to you then you should use COM. If you are happy to accept that restriction then you can carry on as you are.
I don't know if any technology exists to do this.
I do know that I worked with a system very similar to this. We used XML files to describe the various classes that different modules made available. Our equivalent of ModuleManager would parse the xml files to determine what to create for the user at run time based on the class name they provided and the configuration of the system. (Requesting an object that implemented interface 'I' could give back any of objects 'A', 'B' or 'C' depending on how the system was configured.)
The big gotcha we found was that the system was very brittle and at times hard to debug/understand. Just reading through the code, it was often near impossible to see what concrete class was being instantiated. We also found that maintaining the XML created more bugs and overhead than expected.
If I was to do this again, I would keep the design pattern of exposing classes from DLL's through interfaces, but I would not try to build a central registry of classes, nor would I derive everything from a base class such as IObject.
I would instead make each module responsible for exposing its own factory functions(s) to instantiate objects.

Custom COM Implementation?

I'm looking to implement a custom implementation of COM in C++ on a UNIX type platform to allow me to dynamically load and link object oriented code. I'm thinking this would be based on a similar set of functionality that POSIX provides to load and call dll's ie dlopen, dlsym and dlclose.
I understand that the general idea of COM is that you link to a few functions ie QueryInterface, AddRef and Release in a common dll (Kernel32.dll) which then allows you to access interfaces which are just a table of function pointers encapsulated with a pointer to the object for which the function pointers should be called with. These functions are exposed through IUnknown which you must inherit off of.
So how does this all work? Is there a better way to dynamically link and load to object oriented code? How does inheritance from a dll work - does every call to the base class have to be to an exposed member function i.e private/protected/public is simply ignored?
I'm quite well versed in C++ and template meta-programming and already have a fully reflective C++ system i.e member properties, member functions and global/static functions that uses boost.
A couple of things to keep in mind:
The power of COM comes largely from the IDL and the midl compiler. It allows a verry succint definition of the objects and interfaces with all the C/C++ boilerplate generated for you.
COM registration. On Windows the class IDs (CLSID) are recorded in the registry where they are associated with the executable. You must provide similar functionality in the UNIX environment.
The whole IUnknown implementation is fairly trivial, except for QueryInterface which works when implemented in C (i.e. no RTTI).
A whole another aspect of COM is IDispatch - i.e. late bound method invocation and discovery (read only reflection).
Have a look at XPCOM as it is a multi-platform COM like environment. This is really one of those things you are better off leveraging other technologies. It can suck up a lot of the time better spent elsewhere.
I'm looking to implement a custom implementation of COM in C++ on a UNIX type platform to allow me to dynamically load and link object oriented code. I'm thinking this would be based on a similar set of functionality that POSIX provides to load and call dll's ie dlopen, dlsym and dlclose.
At its simplest level, COM is implemented with interfaces. In c++, if you are comfortable with the idea of pure virtual, or abstract base classes, then you already know how to define an interface in c++
struct IMyInterface {
void Method1() =0;
void Method2() =0;
};
The COM runtime provides a lot of extra services that apply to the windows environment but arn't really needed when implementing "mini" COM in a single application as a means to dynamically link to a more OO interface than traditionally allowed by dlopen, dlsym, etc.
COM objects are implemented in .dll, .so or .dylib files depending on your platform. These files need to export at least one function that is standardized: DllGetClassObject
In your own environment you can prototype it however you want but to interop with the COM runtime on windows obviously the name and parameters need to conform to the com standard.
The basic idea is, this is passed a pointer to a GUID - 16 bytes that uniquely are assigned to a particular object, and it creates (based on the GUID) and returns the IClassFactory* of a factory object.
The factory object is then used, by the COM runtime, to create instances of the object when the IClassFactory::CreateInstance method is called.
So, so far you have
a dynamic library exporting at least one symbol, named "DllGetClassObject" (or some variant thereof)
A DllGetClassObject method that checks the passed in GUID to see if and which object is being requested, and then performs a "new CSomeObjectClassFactory"
A CSomeObjectClassFactory implementation that implements (derives from) IClassFactory, and implements the CreateInstance method to "new" instances of CSupportedObject.
CSomeSupportedObject that implements a custom, or COM defined interface that derives from IUnknown. This is important because IClassFactory::CreateInstance is passed an IID (again, a 16byte unique id defining an interface this time) that it will need to QueryInterface on the object for.
I understand that the general idea of COM is that you link to a few functions ie QueryInterface, AddRef and Release in a common dll (Kernel32.dll) which then allows you to access interfaces which are just a table of function pointers encapsulated with a pointer to the object for which the function pointers should be called with. These functions are exposed through IUnknown which you must inherit off of.
Actually, COM is implemented by OLE32.dll which exposes a "c" api called CoCreateInstance. The app passed CoCreateInstance a GUID, which it looks up in the windows registry - which has a DB of GUID -> "path to dll" mappings. OLE/COM then loads (dlopen) the dll, calls its DllGetClassObject (dlsym) method, passing in the GUID again, presuming that succeeds, OLE/COM then calls the CreateInstance and returns the resulting interface to app.
So how does this all work? Is there a better way to dynamically link and load to object oriented code? How does inheritance from a dll work - does every call to the base class have to be to an exposed member function i.e private/protected/public is simply ignored?
implicit inheritance of c++ code from a dll/so/dylib works by exporting every method in the class as a "decorated" symbol. The method name is decorated with the class, and type of every parameter. This is the same way the symbols are exported from static libraries (.a or .lib files iirc). Static or dynamic libraries, "private, protected etc." are always enforced by the compiler, parsing the header files, never the linker.
I'm quite well versed in C++ and template meta-programming and already have a fully reflective C++ system i.e member properties, member functions and global/static functions that uses boost.
c++ classes can typically only be exported from dlls with static linkage - dlls that are loaded at load, not via dlopen at runtime. COM allows c++ interfaces to be dynamically loaded by ensuring that all datatypes used in COM are either pod types, or are pure virtual interfaces. If you break this rule, by defining an interface that tries to pass a boost or any other type of object you will quickly get into a situation where the compiler/linker will need more than just the header file to figure out whats going on and your carefully prepared "com" dll will have to be statically or implicitly linked in order to function.
The other rule of COM is, never pass ownership of an object accross a dynamic library boundary. i.e. never return an interface or data from a dll, and require the app to delete it. Interfaces all need to implement IUnknown, or at least a Release() method, that allows the object to perform a delete this. Any returned data types likewise must have a well known de-allocator - if you have an interface with a method called "CreateBlob", there should probably be a buddy method called "DeleteBlob".
To really understand how COM works, I suggest reading "Essential COM" by Don Box.
Look at the CORBA documentation, at System.ComponentModel in the sscli, the XPCOM parts of the Mozilla codebase. Miguel de Icaza implemented something like OLE in GNOME called Bonobo which might be useful as well.
Depending on what you're doing with C++ though, you might want to look at plugin frameworks for C++ like Yehia. I believe Boost also has something similar.
Edit: pugg seems better maintained than Yehia at the moment. I have not tried it though.
The basic design of COM is pretty simple.
All COM objects expose their functionality through one or more interfaces
All interfaces are derived from the IUnknown interface, thus all interfaces have
QueryInterface, AddRef & Release methods as the first 3 methods of their virtual
function table in a known order
All objects implement IUnknown
Any interface that an object supports can be queried from any other interface.
Interfaces are identified by Globally Unique Identifiers, these are IIDs GUIDs or CLSIDs, but they are all really the same thing. http://en.wikipedia.org/wiki/Globally_Unique_Identifier
Where COM gets complex is in how it deals with allowing interfaces to be called from outside the process where the object resides. COM marshalling is a nasty, hairy, beast. Made even more so by the fact that COM supports both single threaded and multi-threaded programming models.
The Windows implementaion of COM allows objects to be registered (the original use of the Windows registry was for COM). At a minimum the COM registry contains the mapping between the unique GUID for a COM object, and the library (dll) that contains it's code.
For this to work. DLLs that implement COM objects must have a ClassFactory - an entry point in the DLL with a standard name that can be called to create one of the COM objects the DLL implements. (In practice, Windows COM gets an IClassFactory object from this entry point, and uses that to create other COM objects).
so that's the 10 cent tour, but to really understand this, you need to read Essential COM by Don Box.
You may be interested in the (not-yet)Boost.Extension library.