When to use COM

Started by
11 comments, last by Uphoreum 15 years, 9 months ago
Up until now, I've just used __declspec on the classes in order to create DLLs, but I haven't created COM classes and done the whole COM thing. My question is, when should you make use of COM and when should you not? It seems like the only COM libraries I've come across are the ones supplied by Microsoft such as the DirectX libraries.
Advertisement
Do you really mean COM, or do you mean abstract classes? I wouldn't recommend using COM unless you really need to (I.e. you need to share classes across multiple processes or suchlike).

However, I'd recommend using abstract classes over __declspec almost all the time, since it keeps all of the implementation details hidden in the DLL, and is likely to be just as efficient.
By abstract classes, do you just mean classes with virtual methods?
Don't you need to use __declspec in order to create the .def and the .lib?
I use COM to get C# objects into unmanaged C++. Sometimes the .net library is too valuable to give up.

__declspec isn't really useful for nontrivial interop because it constrains you to c primitives when you cross language or compiler boundaries.
Quote:Original post by Uphoreum
By abstract classes, do you just mean classes with virtual methods?
Classes with only virtual methods, yes.

Quote:Original post by Uphoreum
Don't you need to use __declspec in order to create the .def and the .lib?
You usually use __declspec to export a single factory function. You don't need a .def file at all.

You'll end up with a header like:
class IClass{public:   IClass() {}   virtual ~IClass() {}   virtual void DoSomething() = 0;   // Other methods here};#ifdef MYDLL_EXPORTS#   define MYDLL_LINKAGE __declspec(dllexport)#else#   define MYDLL_LINKAGE __declspec(dllimport)#endifMYDLL_LINKAGE IClass* CreateClass();
It seems to me that I would be able to use the CreateClass method, but if I tried to use any methods of the class it returned, it would complain that it couldn't link because the class was not being exported. Is this not the case?

Also, wouldn't that create a .DEF because of the __declspec on the CreateClass method?

Maybe I just don't quite understand what __declspec does.
Quote:Original post by Uphoreum
It seems to me that I would be able to use the CreateClass method, but if I tried to use any methods of the class it returned, it would complain that it couldn't link because the class was not being exported. Is this not the case?
The way it works is that you expose an interface to the EXE, and implement the class in the DLL. See below...

Quote:Original post by Uphoreum
Also, wouldn't that create a .DEF because of the __declspec on the CreateClass method?

Maybe I just don't quite understand what __declspec does.
I'm not actually sure; if it does, you don't need it for this anyway.

The way abstract classes work is like so.

You have a public header, that's exposed to the EXE (Which is the header code in my last post), a private header that is only included in DLL code, and your implementation file (Which is in the DLL). You derive from the abstract class in the private header, and provide an implementation in your implementation file. That way, all the EXE sees is the public header, which completely hides any details like private functions and member variables.

The private header for the public header in my last post might be:
class ClassImpl : public IClass{public:   ClassImpl();   virtual ~ClassImpl();   virtual void DoSomething();   // Other methods here};


And the .cpp file might be:
ClassImpl::ClassImpl(){   // Code here}ClassImpl::~ClassImpl(){   // Code here}void ClassImpl::DoSomething(){   // Code here}// Factory functionMYDLL_LINKAGE IClass* CreateClass(){   return new ClassImpl();}

You may want a DestroyClass() function too (that just delete's the class), or a Release() member function that just calls delete this;.
The CreateClass method is fragile - it will work if the dll was compiled with *identical* language, compiler version, and build configuration as the application linking with it. Otherwise it will probably crash otherwise, or if you're unlucky give you errors that make no sense.

If that's ok for your needs, and you are statically linking the DLL (you are unless you're calling win32 API LoadLibrary() yourself), make sure you link with yourdll.lib. this small lib defines proxies for your dll exports, and forwards to the actual address of the export in your dll.
Okay, that makes sense now.

I'm not too concerned about it not playing nicely with other compilers (or languages). It seems like most libraries require that you download compiler specific binaries anyway.

Alright, I think I'm good for now. Thanks!
Quote:Original post by thedustbustr
The CreateClass method is fragile - it will work if the dll was compiled with *identical* language, compiler version, and build configuration as the application linking with it. Otherwise it will probably crash otherwise, or if you're unlucky give you errors that make no sense.

If that's ok for your needs, and you are statically linking the DLL (you are unless you're calling win32 API LoadLibrary() yourself), make sure you link with yourdll.lib. this small lib defines proxies for your dll exports, and forwards to the actual address of the export in your dll.
It just won't link if the compiler config is different, and if you're doing static linking, you're bound to that anyway. If you want dynamic linking, and you want to solve that, you can just put CreateClass() in a extern "C" block.

This topic is closed to new replies.

Advertisement