• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Strange dynamic_cast problem
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Strange dynamic_cast problem


  • Subject: Re: Strange dynamic_cast problem
  • From: Eric Gorr <email@hidden>
  • Date: Tue, 4 Nov 2008 10:26:16 -0500

On Nov 3, 2008, at 10:20 PM, Chris Suter wrote:

On Tue, Nov 4, 2008 at 9:09 AM, Eric Gorr <email@hidden> wrote:

I have a strange problem with a dynamic_cast.

I have put together a simple test project which can be found at:

http://ericgorr.net/LibraryLoading.zip

which demonstrates the problem.

I think you've hit a common problem with loading libraries at runtime which is: by providing a definition of A and B's destructors in the shared header, the compiler puts a copy of these, the virtual table and the RTTI in each of the libraries so that when you load them, there are two copies floating about and that confuses dynamic_cast.


Thank you again for your comments.

I've been looking into the issue a bit more and thought that if it were possible to make the destructors pure virtual functions as well, then that would solve the problem.

Googling for "pure virtual destructors c++", I came across:

http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter15_024.html

While it seems strange, apparently this is allowed in C++.

So, if I changed Shared.h to look like:

*****
*****
#define VISIBLE __attribute__ ((visibility("default")))

class VISIBLE A
{
public:
    virtual ~A( void )          = 0;
    virtual void Func( void )   = 0;
};
A::~A() {}

class VISIBLE B : public A
{
public:
    virtual ~B( void )          = 0;
    virtual void Func1( void )  = 0;
};
B::~B() {}

extern "C" VISIBLE A *GetA( void );
*****
*****

everything worked in all three cases.


And comments on this solution? Any reason why this wouldn't be perfectly valid?



nm on the libraries and application produces:

~/Desktop/LibraryLoading/build/Debug/LibraryA.bundle/Contents/MacOS $nm LibraryA || c++filt
00000d28 T _GetA
00000d54 t __ZN1AC2Ev
00000c12 T __ZN1AD0Ev
00000bd4 T __ZN1AD1Ev
00000b96 T __ZN1AD2Ev
00000d78 t __ZN1BC2Ev
00000ce0 T __ZN1BD0Ev
00000c98 T __ZN1BD1Ev
00000c50 T __ZN1BD2Ev
00000e70 t __ZN4BImp4FuncEv
00000e8a t __ZN4BImp5Func1Ev
00000dac t __ZN4BImpC1Ev
00000e28 t __ZN4BImpD0Ev
00000de0 t __ZN4BImpD1Ev
00001040 S __ZTI1A
00001034 S __ZTI1B
00001028 S __ZTI4BImp
00000ea4 S __ZTS1A
00000ea7 S __ZTS1B
00000eaa S __ZTS4BImp
00001060 S __ZTV1A
00001048 S __ZTV1B
00001010 S __ZTV4BImp
U __ZTVN10__cxxabiv117__class_type_infoE
U __ZTVN10__cxxabiv120__si_class_type_infoE
U __ZdlPv
U __Znwm
U ___cxa_pure_virtual
U ___gxx_personality_v0
00000b88 t __dyld_func_lookup
00000000 t __mh_bundle_header
00000b74 t dyld_stub_binding_helper


~/Desktop/LibraryLoading/build/Debug/LibraryB.bundle/Contents/MacOS $nm LibraryB | c++filt
00000e1e T A::~A()
00000de0 T A::~A()
00000da2 T A::~A()
00000eec T B::~B()
00000ea4 T B::~B()
00000e5c T B::~B()
0000101c S typeinfo for A
00001010 S typeinfo for B
00000fb9 S typeinfo name for A
00000fb6 S typeinfo name for B
00001040 S vtable for A
00001028 S vtable for B
U vtable for __cxxabiv1::__class_type_info
U vtable for __cxxabiv1::__si_class_type_info
U operator delete(void*)
U ___cxa_pure_virtual
U ___dynamic_cast
U ___gxx_personality_v0
00000d94 t __dyld_func_lookup
00000000 t __mh_bundle_header
00000f34 T _test
00000d80 t dyld_stub_binding_helper


(built with CASE_B = 1 )
~/Desktop/LibraryLoading/build/Debug/LibraryLoading.app/Contents/MacOS $nm LibraryLoading | c++filt
U _CFBundleCopyResourceURL
U _CFBundleCreate
U _CFBundleGetFunctionPointerForName
U _CFBundleGetMainBundle
0000200c D _NXArgc
00002008 D _NXArgv
00001e3e T GetInstance()
00001e04 T OpenExternalDynamicLibrary(__CFURL const*, __CFBundle*&)
00001cee T A::~A()
00001cb0 T A::~A()
00001c72 T A::~A()
00001dbc T B::~B()
00001d74 T B::~B()
00001d2c T B::~B()
00002054 S typeinfo for A
00002048 S typeinfo for B
00001f42 S typeinfo name for A
00001f45 S typeinfo name for B
00002060 S vtable for A
00002030 S vtable for B
U vtable for __cxxabiv1::__class_type_info
U vtable for __cxxabiv1::__si_class_type_info
U operator delete(void*)
U ___CFConstantStringClassReference
U ___cxa_pure_virtual
U ___gxx_personality_v0
00002000 D ___progname
00001c64 t __dyld_func_lookup
00001000 A __mh_execute_header
00002004 D _environ
U _exit
U _kCFAllocatorDefault
00001eb8 T _main
00001c50 t dyld_stub_binding_helper
00001c10 T start





_______________________________________________ Do not post admin requests to the list. They will be ignored. Xcode-users mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
  • Follow-Ups:
    • Re: Strange dynamic_cast problem
      • From: Eric Gorr <email@hidden>
    • Re: Strange dynamic_cast problem
      • From: "Chris Suter" <email@hidden>
References: 
 >Strange dynamic_cast problem (From: Eric Gorr <email@hidden>)
 >Re: Strange dynamic_cast problem (From: "Chris Suter" <email@hidden>)
 >Re: Strange dynamic_cast problem (From: Eric Gorr <email@hidden>)

  • Prev by Date: Re: Strange dynamic_cast problem
  • Next by Date: How to disable GUI plist editor? (it destroys user data)
  • Previous by thread: Re: Strange dynamic_cast problem
  • Next by thread: Re: Strange dynamic_cast problem
  • Index(es):
    • Date
    • Thread