469,306 Members | 1,794 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,306 developers. It's quick & easy.

exporting a C++ object in a DLL

I have a class that contains a std::map variable. I need to export the
class via a DLL. the class looks something like this:

class MyClass
{
public:
MyClass();
MyClass(const MyClass&);

private:
MyClass& operator=(const MyClass&);

typedef std::map<SomeKey, SomethingElseTreasureChest ;

TreasureChest m_treasures;
};
Jul 1 '07 #1
15 7145
you can either __declspec(dllexport) every member of the class that
you want to export, or __declspec(dllexport) the class definition.

In the "dll user" code you should declare the class with
__declspec(dllimport). There are standard ways to do that using
macros. See
http://www.codeproject.com/dll/SimpleDll2.asp

or
http://msdn2.microsoft.com/en-US/lib...4d(VS.80).aspx

Good Bye
QbProg

Jul 1 '07 #2


QbProg wrote:
you can either __declspec(dllexport) every member of the class that
you want to export, or __declspec(dllexport) the class definition.

In the "dll user" code you should declare the class with
__declspec(dllimport). There are standard ways to do that using
macros. See
http://www.codeproject.com/dll/SimpleDll2.asp

or
http://msdn2.microsoft.com/en-US/lib...4d(VS.80).aspx

Good Bye
QbProg
See: http://support.microsoft.com/kb/168958

Relevant text: The only STL container that can currently be exported is
vector. The other containers (that is, map, set, queue, list, deque) all
contain nested classes and cannot be exported.

The article was last reviewed in September 2005 - I wanted to know if it
is now possible to export std::map from a DLL
Jul 2 '07 #3

"Grey Alien" <gr**@andromeda.comwrote in message
news:uY*********************@bt.com...
>I have a class that contains a std::map variable. I need to export the
class via a DLL. the class looks something like this:
No you don't. Create an interface (class with pure virtual pointers),
derive the implementation from it, and share only the interface. You do
that by putting the interface definition in a public header file. No
__declspec(dllexport) statement is needed.

Exporting C++ classes is very bad news. __declspec(dllexport) should be
used only for 'extern "C"' functions.
>
class MyClass
{
public:
MyClass();
MyClass(const MyClass&);

private:
MyClass& operator=(const MyClass&);

typedef std::map<SomeKey, SomethingElseTreasureChest ;

TreasureChest m_treasures;
};


Jul 2 '07 #4


Ben Voigt [C++ MVP] wrote:
"Grey Alien" <gr**@andromeda.comwrote in message
news:uY*********************@bt.com...
>>I have a class that contains a std::map variable. I need to export the
class via a DLL. the class looks something like this:


No you don't.
Yes I do. I know what I want.

Create an interface (class with pure virtual pointers),
derive the implementation from it, and share only the interface. You do
that by putting the interface definition in a public header file. No
__declspec(dllexport) statement is needed.
You are assuming that the DLL will be consumed by a C++ client. That is
not the case. Besides, how can you possibly use code in another
compilation unit if you don't link into it (either statically or
dynamically).?
>
Exporting C++ classes is very bad news. __declspec(dllexport) should be
used only for 'extern "C"' functions.
Not necessarily true. In my case, I am taking care of the C++ "name
mangling" - through various policies and procedures (didn't include info
because it is orthogonal to my original question).
>
>>class MyClass
{
public:
MyClass();
MyClass(const MyClass&);

private:
MyClass& operator=(const MyClass&);

typedef std::map<SomeKey, SomethingElseTreasureChest ;

TreasureChest m_treasures;
};



Jul 2 '07 #5
Grey Alien wrote:
You are assuming that the DLL will be consumed by a C++ client. That is
not the case. Besides, how can you possibly use code in another
compilation unit if you don't link into it (either statically or
dynamically).?
Grey:

You want to export a class containing an std::map and it will not be
consumed by a C++ client?

Ben's advice might have seemed a little fierce, but basically I agree
with it. You will save yourself a lot of future headaches if you design
your class with a pure virtual interface (and methods using simple types).

--
David Wilkinson
Visual C++ MVP
Jul 2 '07 #6


David Wilkinson wrote:
Grey Alien wrote:
>You are assuming that the DLL will be consumed by a C++ client. That
is not the case. Besides, how can you possibly use code in another
compilation unit if you don't link into it (either statically or
dynamically).?


Grey:

You want to export a class containing an std::map and it will not be
consumed by a C++ client?

Ben's advice might have seemed a little fierce, but basically I agree
with it. You will save yourself a lot of future headaches if you design
your class with a pure virtual interface (and methods using simple types).
Dave:

That may be the case, but the fact remains that the class whose methods
are invoked needs to contain a map member variable. At the moment, I'm
getting this annoying warning:

warning C4251: 'theManager::m_signalMap' : class 'std::map<_Kty,_Ty>'
needs to have dll-interface to be used by clients of class 'theManager'

- which seems to imply that std::map can be exported - which contradicts
the (outdated) article on the MSN site. So do I heed the warning and
export the data type (preferred) or do ignore it (with potentially
disastrous consequences)?
Jul 2 '07 #7
Never mind, I found the solution here:
http://caseys.kcfilms.com/2006/01/us...ross_dll_b.php
Jul 2 '07 #8

"Grey Alien" <gr**@andromeda.comwrote in message
news:1t******************************@bt.com...
>

Ben Voigt [C++ MVP] wrote:
>"Grey Alien" <gr**@andromeda.comwrote in message
news:uY*********************@bt.com...
>>>I have a class that contains a std::map variable. I need to export the
class via a DLL. the class looks something like this:


No you don't.

Yes I do. I know what I want.

Create an interface (class with pure virtual pointers),
>derive the implementation from it, and share only the interface. You do
that by putting the interface definition in a public header file. No
__declspec(dllexport) statement is needed.

You are assuming that the DLL will be consumed by a C++ client. That is
not the case. Besides, how can you possibly use code in another
compilation unit if you don't link into it (either statically or
dynamically).?
If your client isn't C++, the prohibition on __declspec(dllexport) of
classes becomes absolutely instead of just a really good idea.

What do you mean by "don't link into it"? You are creating a DLL, right?
"dynamically linked library" If you create an interface, then the compiler
links the interface v-table to the implementations. The client only needs
the interface definition.

Jul 4 '07 #9

"Grey Alien" <gr**@andromeda.comwrote in message
news:pK******************************@bt.com...
>

David Wilkinson wrote:
>Grey Alien wrote:
>>You are assuming that the DLL will be consumed by a C++ client. That is
not the case. Besides, how can you possibly use code in another
compilation unit if you don't link into it (either statically or
dynamically).?


Grey:

You want to export a class containing an std::map and it will not be
consumed by a C++ client?

Ben's advice might have seemed a little fierce, but basically I agree
with it. You will save yourself a lot of future headaches if you design
your class with a pure virtual interface (and methods using simple
types).

Dave:

That may be the case, but the fact remains that the class whose methods
are invoked needs to contain a map member variable. At the moment, I'm
getting this annoying warning:

warning C4251: 'theManager::m_signalMap' : class 'std::map<_Kty,_Ty>'
needs to have dll-interface to be used by clients of class 'theManager'
- which seems to imply that std::map can be exported - which contradicts
the (outdated) article on the MSN site. So do I heed the warning and
export the data type (preferred) or do ignore it (with potentially
disastrous consequences)?
There is no contradiction, both are correct. std::map should not be
exported, and because of that, it should not be used by clients of
"theManager". Since it is a private implementation detail, why would that
present a problem? Clients aren't using it.

Jul 4 '07 #10


Ben Voigt [C++ MVP] wrote:
>
"Grey Alien" <gr**@andromeda.comwrote in message
news:1t******************************@bt.com...
>>

Ben Voigt [C++ MVP] wrote:
>>"Grey Alien" <gr**@andromeda.comwrote in message
news:uY*********************@bt.com...

I have a class that contains a std::map variable. I need to export
the class via a DLL. the class looks something like this:

No you don't.


Yes I do. I know what I want.

Create an interface (class with pure virtual pointers),
>>derive the implementation from it, and share only the interface. You
do that by putting the interface definition in a public header file.
No __declspec(dllexport) statement is needed.
Sounds like you're describing the Pimpl pattern. I haven't used it
myself before, though it does sound like a good idea (I can't use it in
my current project though - because legacy code already exports classes).

However, as a matter of interest, if only the interface is specified
(via pure virtuals in a header) - surely, it means that EACH child class
will have to implement the same functionality allover again. The idea
for exporting classes was for code reuse - which you seem to be losing,
using the Pimpl pattern you describe. Am I missing something?
Jul 4 '07 #11
Grey Alien wrote:
Sounds like you're describing the Pimpl pattern. I haven't used it
myself before, though it does sound like a good idea (I can't use it in
my current project though - because legacy code already exports classes).
Grey:

Pimpl and Abstract Base Class (ABC) are not the same thing. A pimpl
class is not a pure interface.

--
David Wilkinson
Visual C++ MVP
Jul 4 '07 #12

"Grey Alien" <gr**@andromeda.comwrote in message
news:rJ******************************@bt.com...
>

Ben Voigt [C++ MVP] wrote:
>>
"Grey Alien" <gr**@andromeda.comwrote in message
news:1t******************************@bt.com...
>>>

Ben Voigt [C++ MVP] wrote:

"Grey Alien" <gr**@andromeda.comwrote in message
news:uY*********************@bt.com...

I have a class that contains a std::map variable. I need to export the
class via a DLL. the class looks something like this:

No you don't.
Yes I do. I know what I want.

Create an interface (class with pure virtual pointers),

derive the implementation from it, and share only the interface. You
do that by putting the interface definition in a public header file.
No __declspec(dllexport) statement is needed.

Sounds like you're describing the Pimpl pattern. I haven't used it myself
before, though it does sound like a good idea (I can't use it in my
current project though - because legacy code already exports classes).

However, as a matter of interest, if only the interface is specified (via
pure virtuals in a header) - surely, it means that EACH child class will
have to implement the same functionality allover again. The idea for
exporting classes was for code reuse - which you seem to be losing, using
the Pimpl pattern you describe. Am I missing something?
Yup. The interface can be implemented in a base class which provides the
implementation, and each derived (or child if you prefer) class inherits.
Only the interface cannot have any implementation, but it can participate in
a full hierarchy.

Jul 4 '07 #13


Ben Voigt [C++ MVP] wrote:
>
>However, as a matter of interest, if only the interface is specified
(via pure virtuals in a header) - surely, it means that EACH child
class will have to implement the same functionality allover again. The
idea for exporting classes was for code reuse - which you seem to be
losing, using the Pimpl pattern you describe. Am I missing something?


Yup. The interface can be implemented in a base class which provides
the implementation, and each derived (or child if you prefer) class
inherits. Only the interface cannot have any implementation, but it can
participate in a full hierarchy.
But if the interface is implemented in a base class, then that base
class needs to be exported, so that its derived classes can correctly
link to the approriate compilation units - so we end up in the same
situation, i.e having to export the (base) class.

Unless I am misunderstanding you, your approach ensures that if we have
a Widget class (say), we will make its interface available as an ABC,
and then every module that needs to use a Widget class implement the
interface. This is not scaleable - as N different classes (in different
library modules) that delegate to the Widget class will have to write N
implementations for the Widget class. The duplicity of effort that
entails (not to mention the increased scope for errors/nightmare code
maintenance etc) is so ridiculous that I have to assume that I have
misunderstood you - please clarify.
Jul 5 '07 #14

"Grey Alien" <gr**@andromeda.comwrote in message
news:1M*********************@bt.com...
>

Ben Voigt [C++ MVP] wrote:
>>
>>However, as a matter of interest, if only the interface is specified
(via pure virtuals in a header) - surely, it means that EACH child class
will have to implement the same functionality allover again. The idea
for exporting classes was for code reuse - which you seem to be losing,
using the Pimpl pattern you describe. Am I missing something?


Yup. The interface can be implemented in a base class which provides the
implementation, and each derived (or child if you prefer) class inherits.
Only the interface cannot have any implementation, but it can participate
in a full hierarchy.

But if the interface is implemented in a base class, then that base class
needs to be exported, so that its derived classes can correctly link to
the approriate compilation units - so we end up in the same situation, i.e
having to export the (base) class.

Unless I am misunderstanding you, your approach ensures that if we have a
Widget class (say), we will make its interface available as an ABC, and
then every module that needs to use a Widget class implement the
interface. This is not scaleable - as N different classes (in different
library modules) that delegate to the Widget class will have to write N
implementations for the Widget class. The duplicity of effort that entails
(not to mention the increased scope for errors/nightmare code maintenance
etc) is so ridiculous that I have to assume that I have misunderstood
you - please clarify.
The module that you think you want to dllexport a class from...

Instead you declare an interface (class with only pure virtual functions) in
its public header file. Include this from the clients. Since the members
are pure virtual, the header has the complete definition and no
declspec(dllexport) is needed.

Now in that module providing the class, you create a declspec(dllexport)
extern "C" function (or several) for creating instances, called a factory
method. The instances are of a class that implements the interface. If you
want polymorphism between multiple implementations, multiple classes can
provide an implementation by inheriting the interface. These multiple
classes can each implement the interface independently, or they can inherit
from each other to share an interface.

Jul 5 '07 #15
Grey Alien wrote:
Additionally, is there a name for the mechanism/methodolgy you describe
?. I would be grateful for any links on where to read up more about this
- and maybe convince myself to refactor the existing code to use this
methodology. Tks
Grey:

I call this method "Do It Yourself COM."

--
David Wilkinson
Visual C++ MVP
Jul 5 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by chetan | last post: by
6 posts views Thread by Steve Richter | last post: by
3 posts views Thread by Bilgehan.Balban | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by harlem98 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.