|
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
|