When to use COM
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.
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.
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?
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.
__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 UphoreumClasses with only virtual methods, yes.
By abstract classes, do you just mean classes with virtual methods?
Quote:Original post by UphoreumYou usually use __declspec to export a single factory function. You don't need a .def file at all.
Don't you need to use __declspec in order to create the .def and the .lib?
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.
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 UphoreumThe way it works is that you expose an interface to the EXE, and implement the class in the DLL. See below...
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?
Quote:Original post by UphoreumI'm not actually sure; if it does, you don't need it for this anyway.
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.
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.
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!
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 thedustbustrIt 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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement