Re: Assistance required, exporting a class from a DLL
"Ulrich Eckhardt" wrote:
This seems like a lot of work and it initially is, but it allows
you to not introduce any code that only works around linking
quirks into your code. In fact it allows a completely 'natural'
use of the library code, including important things like
exceptions. Further, selecting the right lib should then be done
using #pragma comment(lib, ..) and by checking preprocessor
macros, which saves much time when using the library, too.
Agree. This is how software modules should be distributed both
outside and inside a company.
1. It is not necessary to export the classes of all data
members, only that they are available to the one that includes
the library. If it was necessary, you would also get an error
(hopefully) and not a warning you can ignore.
Why not to play safe and add it? Especially when you get a warning
of level 1 about it.
Note the fine distinction between exporting and making
available: In particular for cases like std::map<>, it means
that since it is available to both the library and the code that
uses it (you must include the header to use it in an exported
interface), there is no need to do anything further, in
particular not to export it from your DLL. It would even be
wrong to export it, since that would mean that another library
exporting it, too, would cause a conflict.
Actually, if you use an unexported instantiation of a standard
container as a data member, then you won't see it exported, but
you will get C4251 warning (level 1) about such member.
However, if you use an unexported instantiation of a standard
container as a base class, then compiler will export everything
from this standard container. Also, you'll see the C4275 warning
(level 2). Although MSDN says that one can ignore this warning if
the error message refers to `_Container_base', for me it seems as
dirty solution. And what about `_Container_base_secure'? MSDN
doesn't mention it at all (either deliberately or by unfortunate
omission).
2. I know that I exported a class derived from
std::pair<unsigned,unsigned> from a library, and the compiler
actually exported not only symbols of the derived class but also
symbols of the baseclass. I personally consider that a bug, and
I believe it also isn't present in all MS compilers [...].
Why do you think it is a bug? Suppose client creates an instance
of the exported object. Now compiler must be able to call its
constructor, check availability and visibility of base class
contructior etc..
They probably could encapsulate all derived<-->base machinery in
methods of derived class, so only these methods would be exported.
However, they decided to export base class in its entirety and let
the clinet side compiler to make certain decisions. I see it as an
implementation detail, not a bug.
One more suggestion on your article: your suggestion to use a
pure virtual interface and using a Release() function instead of
the destructor would actually benefit from having a protected
(nonvirtual) destructor. This would make it impossible for
clients to invoke it accidentally.
Thanks. This is a good point.
Alex