RE: [boost] Explicit instantiation of boost::shared_ptr<SomeClasss>

-----Original Message----- From: Peter Dimov [mailto:pdimov@mmltd.net] Sent: Thursday, March 11, 2004 4:48 PM To: boost@lists.boost.org Subject: Re: [boost] Explicit instantiation of boost::shared_ptr<SomeClasss>
Greg Clayton wrote:
I am trying to do explicitly instantiate specific shared_ptr class for export from a Win32 DLL (currently with MSVC6, and eventually in VS2003).
First things first. Why do you need to do that? Have you tried not exporting it, have you encountered any problems?
Yes, shared pointers can't be created and handed off from DLL to DLL the way they are currently implemented. If DLL A has an STL container of shared pointers, and DLL B gets _dynamically_ loaded and adds an item to DLL A's container (creates a shared pointer to an object, and DLL B adds that shared pointer through an interface it to DLL A's STL container of shared pointers), DLL B can not be unloaded. If DLL B does get unloaded you will crash when your STL container goes out of scope (when it tries to delete the owned pointer). The virtual function table for the shared pointer lives in the DLL that creates it if you just use something like: typedef boost::shared_ptr<SomeClass> SomeClassSP; in a header file that comes from DLL A (for other DLLs to link to). So I need to instantiate and export everything for that shared pointer from DLL A (since it is the DLL that owns the STL containers of objects) so that the vtable stays valid for the lifetime of the shared pointer object.
[...]
When I look through the exports, some needed class functions seem to be missing from the DLL, and linking fails. Most notable are:
void boost::shared_ptr<SomeClass>::reset(SomeClass*)
This function is declared in the shared_ptr header file as: template<class Y> void reset(Y * p);
This is a function template. A template can't be exported, only an instantiation.
template void boost::shared_ptr<SomeClass>::reset(SomeClass*);
should instantiate reset with Y=SomeClass.
After I sent the original email to this list I tried something similar, but it didn't seem to work (didn't see it in my export list). I will try it with VS2003 and see if I have better luck.

Greg Clayton wrote:
-----Original Message----- From: Peter Dimov [mailto:pdimov@mmltd.net] Sent: Thursday, March 11, 2004 4:48 PM To: boost@lists.boost.org Subject: Re: [boost] Explicit instantiation of boost::shared_ptr<SomeClasss>
Greg Clayton wrote:
I am trying to do explicitly instantiate specific shared_ptr class for export from a Win32 DLL (currently with MSVC6, and eventually in VS2003).
First things first. Why do you need to do that? Have you tried not exporting it, have you encountered any problems?
Yes, shared pointers can't be created and handed off from DLL to DLL the way they are currently implemented. If DLL A has an STL container of shared pointers, and DLL B gets _dynamically_ loaded and adds an item to DLL A's container (creates a shared pointer to an object, and DLL B adds that shared pointer through an interface it to DLL A's STL container of shared pointers), DLL B can not be unloaded. If DLL B does get unloaded you will crash when your STL container goes out of scope (when it tries to delete the owned pointer).
Isn't it possible for the DLL C that contains the definition of SomeClass to export shared_ptr<SomeClass> createSomeClass(); which DLL B can now call when it needs a SomeClass? Since ~SomeClass lives in C, it must be available when the last shared_ptr<SomeClass> is destroyed.

"Greg Clayton" <Greg.Clayton@palmsource.com> writes:
Greg Clayton wrote:
I am trying to do explicitly instantiate specific shared_ptr class for export from a Win32 DLL (currently with MSVC6, and eventually in VS2003).
First things first. Why do you need to do that? Have you tried not exporting it, have you encountered any problems?
Yes, shared pointers can't be created and handed off from DLL to DLL the way they are currently implemented.
I don't understand why people keep making this claim. As long as you don't unload DLL B, you're golden. The only other alternative prohibits unloading DLL A. I don't think that dynamically generating a fake DLL to hold the destructors would be appropriate, so IMO shared_ptr is as well-behaved as it can be wrt DLLs.
If DLL A has an STL container of shared pointers, and DLL B gets _dynamically_ loaded and adds an item to DLL A's container (creates a shared pointer to an object, and DLL B adds that shared pointer through an interface it to DLL A's STL container of shared pointers), DLL B can not be unloaded. If DLL B does get unloaded you will crash when your STL container goes out of scope (when it tries to delete the owned pointer). The virtual function table for the shared pointer lives in the DLL that creates it if you just use something like:
typedef boost::shared_ptr<SomeClass> SomeClassSP;
in a header file that comes from DLL A (for other DLLs to link to). So I need to instantiate and export everything for that shared pointer from DLL A (since it is the DLL that owns the STL containers of objects) so that the vtable stays valid for the lifetime of the shared pointer object.
Solution: pass the objects from B to A via std::auto_ptr. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
David Abrahams
-
Greg Clayton
-
Peter Dimov