By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,192 Members | 1,830 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,192 IT Pros & Developers. It's quick & easy.

Subclass as a dynamic library

P: 1
I'm developing a robot control architecture, and am trying to maximize platform independence (robot hardware, not OS) by generating my individual behaviors as dynamic libraries. The individual behaviors are subclasses of the Leaf class, which is in turn a subclass of the Behavior class. I want to keep the Behavior and Leaf objects in the main program but generate the individual behaviors (e.g. Wander) in shared object files so I can load the specific behavior at run time. I want to access the generated objects through the superclass. That is, if included in the code, I would create the object using
Expand|Select|Wrap|Line Numbers
  1. Behavior * myBeh = new Wander;
. This works fine. When using dlopen, I use
Expand|Select|Wrap|Line Numbers
  1. void *hndl = dlopen(filename.c_str(), RTLD_LAZY);  // dynamically load the library, we'll try to handle errors later.
  2.             if(hndl == NULL)
  3.             {
  4.                 cerr << "File Boo Boo: " <<  dlerror() << endl;
  5.                 exit(-1);
  6.             }
  7.             cout << "loaded " << name << " behavior." << endl;
  8.             create_t* create_type = (create_t*) dlsym(hndl, "maker");  // run maker function to generate instance
  9.             if (!create_type)
  10.             {
  11.                 cerr << "Symbol Boo Boo: " << dlerror() << '\n';
  12.                 exit(1);
  13.             }
  14.             beh = create_type();
I keep running into the "Symbol Boo Boo". I suspect the problem is in the creation of my library. The (pertinent) Wander code is
Expand|Select|Wrap|Line Numbers
  1. #include "Wander.h"
  2.  
  3. Wander::Wander()
  4. {
  5.     ...
  6. }
  7.  
  8. Wander::~Wander()
  9. {
  10.     ...
  11. }
  12.  
  13. Behavior * Wander::maker()
  14.     {
  15.         return new Wander;
  16.     };
  17.  
and the Wander.h file is
Expand|Select|Wrap|Line Numbers
  1. #ifndef _WANDER_H
  2. #define _WANDER_H
  3.  
  4. #include <pthread.h>
  5. #include <string>
  6.  
  7. #include "../../State.h"
  8. #include "../Action.h"
  9. #include "../Leaf.h"
  10.  
  11. using namespace std;
  12.  
  13. #define PI 3.14159265359
  14.  
  15. class Wander : public Leaf
  16. {
  17. private:
  18.     pthread_mutex_t mutex;
  19.     pthread_t behaviorthread;
  20.  
  21.     State* curr_state;
  22.     Action* curr_action;
  23.  
  24.     int turnCounter;
  25.     double velocity;
  26.     double turnrate;
  27.  
  28.     void Lock();
  29.     void Unlock();
  30.  
  31.     static void* DummyMain(void*);
  32.  
  33. public:
  34.     Behavior * maker();
  35.     Wander();
  36.     virtual ~Wander();
  37.  
  38.     void StartThread();
  39.     void StopThread();
  40.  
  41.     void Main();
  42.  
  43.     Action* updAction(State* curr_state);
  44.     Action* genAction();
  45. };
  46.  
  47. #endif
  48.  
my Leaf.h file is:
Expand|Select|Wrap|Line Numbers
  1. #ifndef LEAF_H
  2. #define LEAF_H
  3.  
  4. #include "Behavior.h"
  5. #include "Action.h"
  6. /**
  7.  * A simple behavior, that is, one that is comprised of only a
  8.  * single goal.
  9.  */
  10. class Leaf: public Behavior
  11. {
  12. public:
  13.  
  14.     virtual Behavior * maker()
  15.     {
  16.         return NULL;
  17.     };
  18.     Leaf(){}
  19.     virtual ~Leaf()
  20.     {}
  21.  
  22.     virtual Action* genAction()
  23.     {
  24.         return NULL ;
  25.     }
  26.     virtual void StartThread()
  27.     {};
  28.     virtual void StopThread()
  29.     {};
  30. };
  31. #endif /* LEAF_H */
  32.  
Finally, my Behavior.h file is
Expand|Select|Wrap|Line Numbers
  1. #ifndef _BEHAVIOR_H
  2. #define _BEHAVIOR_H
  3.  
  4. #include    <vector>
  5. #include <string>
  6.  
  7. #include    "Action.h"
  8.  
  9. using namespace std;
  10. /**
  11.  * Base class for the robot behaviors.
  12.  */
  13. class Behavior
  14. {
  15. protected:
  16.     string name;
  17. public:
  18.     virtual Behavior * maker()
  19.     {
  20.         return NULL;
  21.     };
  22.     Behavior()
  23.     {}
  24.     virtual ~Behavior()
  25.     {}
  26.  
  27.     /**
  28.      * Generate an Action based on the current State.
  29.      */
  30.     virtual Action* genAction()
  31.     {
  32.         return NULL ;
  33.     }
  34.     virtual void StartThread()
  35.     {}
  36.     ;
  37.     virtual void StopThread()
  38.     {}
  39.     ;
  40. };
  41.  
  42. typedef Behavior * create_t();
  43.  
  44. #endif /* _BEHAVIOR_H */
  45.  
any ideas?
Jan 11 '08 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.