B
BSand0764
Apologies for the length of this message, but I'm having problems
getting an alternate function to be executed via a functor
implementation.
I have two classes (BkgLand and BkgWater) that comprise a portion of a
much larger simulation. These classes exist in separate libraries
although the library that class BkgWater is in links in the library
containing the BkgLand class (sounds confusing I know). In the
simulation architecture that I'm using to implement these classes, the
Land based classes will be instantiated by default and the functors
will be registered for those classes. If the Water class objects are
present within the system I build (i.e. I've built an executable
containing the Water class), then the Water based classes will be
instantiated after the Land classes and those water functors are then
registered (and should take precedence).
When I test the simulation for a Land configuration I see that the
Land based functors execute just fine (and the Water objects aren't
present). When I configure the simulation for a 'Water case', I see
the message that the Land functors are being registered and then the
Water functors are being registered (as I expected), but when the
'Call_m' function is called (from the "Land" side of the simulation),
I get a segmentation fault. I checked for null pointers, but didn't
see evidence of that.
I don't know if :
- I've declared the funcTable arrays correctly and in the
appropriate sections of code (I had several compilation errors prior
to using the approach outlined below).
- There are some kind of scope issues
- Something between the two libraries is missing to allow the
land based side of the program to interpret the registered water
functions.
It almost seems as if the program doesn't know which function really
should be getting used (specFunc_0 from land or from water) when the
Call_m function is invoked for the water configuration.
Something to note, the programming guidelines I was given constrained
me to not compiling / linking libWater.so with the land based code,
only vice-versa is allowed.
Any suggestions would be greatly appreciated. Alf was already a big
help in an earlier question I posted on a related topic. Please see
the following code snippets. I will be glad to provide more
information if needed.
Danny
#ifndef TFUNCTOR_H
#define TFUNCTOR_H
#include "my_config.h"
#include "Struct1.h"
#include "Struct2.h"
BEGIN_MY_NAMESPACE
class TFunctor
{
public:
virtual void Call_m(STRUCT1*, STRUCT2*)=0;
};
END_MY_NAMESPACE
#endif //TFUNCTOR_H
#ifndef SPECFUNCTOR_H
#define SPECFUNCTOR_H
#include "my_config.h"
#include "TFunctor.h"
BEGIN_MY_NAMESPACE
template <class TClass> class TSpecificFunctor : public TFunctor
{
public:
// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFunctor( TClass* _pt2Object, void(TClass::*tfpt)
(STRUCT1*, STRUCT2*) )
{ pt2Object = _pt2Object; fpt = tfpt; };
// override function "call" in base class
virtual void Call_m(STRUCT1* bkgnd, STRUCT2* geo)
{ (*pt2Object.*fpt) (bkgnd, geo);
private:
void (TClass::*fpt) (STRUCT1*, STRUCT2*);
};
END_MY_NAMESPACE
#endif //SPECFUNCTOR_H
#ifndef BKGLAND_H
#define BKGLAND_H
#include "my_config.h"
#include "Struct1.h"
#include "Struct2.h"
BEGIN_MY_NAMESPACE
class BkgLand
{
public:
// Constructor/Destructor
BkgLand() {};
virtual ~BkgLand() {};
void Initialize();
void Update();
TFunctor::TFunctor *funcTable[];
};
END_MY_NAMESPACE
#endif // BKGLAND_H
BKGLAND.cpp Code (compiled in library LIBGround.so):
#include "BkgLand.h"
#Include "SpecFunctor.h"
#include "LandScats.h"
void BkgLand::Initialize( )
cout << "REGISTER LAND FUNCTIONS" << endl;
// init_test function is a public member of the LandScats class
LandScats objLand;
TSpecificFunctor<LandScats> specFunc_0(&objLand,
&LandScats::init_test);
TFunctor::TFunctor *funcTable[] = { &specFunc_0 };
}
void BkgLand::Update()
{
//geom* and bkgndscat* are provided to this class via accessor
methods.
// Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndscat, geom);
}
BKGWATER.cpp Code (compiled in a separate library, LIBWater.so, but
LIBGround is linked in when this library is built):
#include "BkgWater.h"
#include "TFunctor.h"
#include "SpecFunctor.h"
#include "WaterScats.h"
void BkgWater::Initialize()
{
cout << "REGISTER WATER FUNCTIONS" << endl;
// init_test function is a public member of the WaterScats
class
WaterScats objWater;
TSpecificFunctor<WaterScats> specFunc_0( &objWater,
&WaterScats::init_test);
TFunctor::TFunctor *funcTable[] = { &specFunc_0 };
}
#ifndef BKGWATER_H
#define BKGWATER_H
#include "Tfunctor.h"
BEGIN_MY_NAMESPACE
class BkgWater
{
BkgWater();
virtual ~BkgWater();
public:
virtual void Initialize();
TFunctor::TFunctor *funcTable[];
}
END_MY_NAMESPACE
#endif // BKGWATER_H
getting an alternate function to be executed via a functor
implementation.
I have two classes (BkgLand and BkgWater) that comprise a portion of a
much larger simulation. These classes exist in separate libraries
although the library that class BkgWater is in links in the library
containing the BkgLand class (sounds confusing I know). In the
simulation architecture that I'm using to implement these classes, the
Land based classes will be instantiated by default and the functors
will be registered for those classes. If the Water class objects are
present within the system I build (i.e. I've built an executable
containing the Water class), then the Water based classes will be
instantiated after the Land classes and those water functors are then
registered (and should take precedence).
When I test the simulation for a Land configuration I see that the
Land based functors execute just fine (and the Water objects aren't
present). When I configure the simulation for a 'Water case', I see
the message that the Land functors are being registered and then the
Water functors are being registered (as I expected), but when the
'Call_m' function is called (from the "Land" side of the simulation),
I get a segmentation fault. I checked for null pointers, but didn't
see evidence of that.
I don't know if :
- I've declared the funcTable arrays correctly and in the
appropriate sections of code (I had several compilation errors prior
to using the approach outlined below).
- There are some kind of scope issues
- Something between the two libraries is missing to allow the
land based side of the program to interpret the registered water
functions.
It almost seems as if the program doesn't know which function really
should be getting used (specFunc_0 from land or from water) when the
Call_m function is invoked for the water configuration.
Something to note, the programming guidelines I was given constrained
me to not compiling / linking libWater.so with the land based code,
only vice-versa is allowed.
Any suggestions would be greatly appreciated. Alf was already a big
help in an earlier question I posted on a related topic. Please see
the following code snippets. I will be glad to provide more
information if needed.
Danny
#ifndef TFUNCTOR_H
#define TFUNCTOR_H
#include "my_config.h"
#include "Struct1.h"
#include "Struct2.h"
BEGIN_MY_NAMESPACE
class TFunctor
{
public:
virtual void Call_m(STRUCT1*, STRUCT2*)=0;
};
END_MY_NAMESPACE
#endif //TFUNCTOR_H
#ifndef SPECFUNCTOR_H
#define SPECFUNCTOR_H
#include "my_config.h"
#include "TFunctor.h"
BEGIN_MY_NAMESPACE
template <class TClass> class TSpecificFunctor : public TFunctor
{
public:
// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFunctor( TClass* _pt2Object, void(TClass::*tfpt)
(STRUCT1*, STRUCT2*) )
{ pt2Object = _pt2Object; fpt = tfpt; };
// override function "call" in base class
virtual void Call_m(STRUCT1* bkgnd, STRUCT2* geo)
{ (*pt2Object.*fpt) (bkgnd, geo);
private:
void (TClass::*fpt) (STRUCT1*, STRUCT2*);
};
END_MY_NAMESPACE
#endif //SPECFUNCTOR_H
#ifndef BKGLAND_H
#define BKGLAND_H
#include "my_config.h"
#include "Struct1.h"
#include "Struct2.h"
BEGIN_MY_NAMESPACE
class BkgLand
{
public:
// Constructor/Destructor
BkgLand() {};
virtual ~BkgLand() {};
void Initialize();
void Update();
TFunctor::TFunctor *funcTable[];
};
END_MY_NAMESPACE
#endif // BKGLAND_H
BKGLAND.cpp Code (compiled in library LIBGround.so):
#include "BkgLand.h"
#Include "SpecFunctor.h"
#include "LandScats.h"
void BkgLand::Initialize( )
cout << "REGISTER LAND FUNCTIONS" << endl;
// init_test function is a public member of the LandScats class
LandScats objLand;
TSpecificFunctor<LandScats> specFunc_0(&objLand,
&LandScats::init_test);
TFunctor::TFunctor *funcTable[] = { &specFunc_0 };
}
void BkgLand::Update()
{
//geom* and bkgndscat* are provided to this class via accessor
methods.
// Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndscat, geom);
}
BKGWATER.cpp Code (compiled in a separate library, LIBWater.so, but
LIBGround is linked in when this library is built):
#include "BkgWater.h"
#include "TFunctor.h"
#include "SpecFunctor.h"
#include "WaterScats.h"
void BkgWater::Initialize()
{
cout << "REGISTER WATER FUNCTIONS" << endl;
// init_test function is a public member of the WaterScats
class
WaterScats objWater;
TSpecificFunctor<WaterScats> specFunc_0( &objWater,
&WaterScats::init_test);
TFunctor::TFunctor *funcTable[] = { &specFunc_0 };
}
#ifndef BKGWATER_H
#define BKGWATER_H
#include "Tfunctor.h"
BEGIN_MY_NAMESPACE
class BkgWater
{
BkgWater();
virtual ~BkgWater();
public:
virtual void Initialize();
TFunctor::TFunctor *funcTable[];
}
END_MY_NAMESPACE
#endif // BKGWATER_H