From: Pecevski D. <de...@ig...> - 2008-11-04 10:06:47
|
Hi Chris, Christopher Nolan wrote: > I've taken a bit more of a look at this, and it seems that the problem > is in attempting to use runtime type information across shared module > boundaries. The dynamic_cast works for calls within libpcsim, and also > works if called within an extension module, but extension classes > derived from libpcsim classes cannot be correctly examined by the > libpcsim library. I've looked a this, there seems to be a problem with the RTTI across separate c++ libraries, but in relation with multiple inheritance classes. SimObjects that are defined in the extension and are derived just from one Simobject class defined in libpcsim work fine, like in the pcsim extension template example. When the extension SimObjects are derived from multiple classes, like in your case (SimObject and SingleOutputSpikeSener), or they are derived from another class that is defined within the extension module it doesn't seem to work, probably because in this case, for reasons not clear to me currently, the compiler puts another typeinfo RTTI signature for the parent classes (SpikeSender) in the extension module, or doesn't handle correctly the setup of the virtual tables of the newly defined extension class. I need to investigate this a bit further. > I've worked around the issue for the moment by > changing SingleThreadNetwork line 170 from: > > SpikeSender *ss = dynamic_cast<SpikeSender*>( src_obj ); > > to: > > SpikeSender *ss = > static_cast<SpikeSender*>( dynamic_cast<void*>( src_obj ) ); > > and similarly in the MultiThreadNetwork class. I'm not particularly > sure of the rules for pointer casting in class hierarchies, but as far > as I understand it, the dynamic_cast<void*> may not operate correctly if > the start of the derived (extension) class is not the same as the start > of the SimObject* class? > dynamic_cast<void *> here will give the pointer to the top of the class, that is the pointer to first class the sim object inherits from (we are not using any virtual inheritance), which in case of the TestSpikeSender is SimObject. Simply casting it to SpikeSender should not be safe since the void * pointer doesn't point to the SpikeSender part of the TestSpikeSender object. I've run a simple example to test this in C++: -------------- SpikingInputNeuron nrn; SpikingInputNeuron *nrn_p = &nrn; SimObject *obj_p = &nrn; SpikeSender *sndr_p = &nrn; cerr << " nrn ptr=" << nrn_p << endl; cerr << " obj ptr=" << obj_p << endl; cerr << " spk sender ptr=" << sndr_p << endl; SpikeSender * dyn_sndr_p = dynamic_cast<SpikeSender *>(obj_p); SpikeSender * st_sndr_p = static_cast<SpikeSender *>(dynamic_cast<void *>(obj_p)); cerr << " dyn sender ptr=" << dyn_sndr_p << endl; cerr << " st sender ptr=" << st_sndr_p << endl; -------------- and the output was: --------------------------- nrn ptr=0x7fff7d125490 obj ptr=0x7fff7d125490 spk sender ptr=0x7fff7d125498 dyn sender ptr=0x7fff7d125498 st sender ptr=0x7fff7d125490 --------------------------- You can see that the dynamic_cast from SimObject and the static_cast from void do not return the same pointer. The following articles explains further the matter: http://carcino.gen.nz/tech/cpp/multiple_inheritance_this.php#static_cast_cant_downcast http://www.phpcompiler.org/articles/virtualinheritance.html Until we find out an appropriate solution, you could compile your custom class together within the main pcsim code. Cheers, Dejan |