dynamically instantiate a class

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sumit Nagpal

    #1

    dynamically instantiate a class

    Hi All,

    My application reads a 'Class' name (as a string) from a file at Run time.
    Can i create an instance this Class ?

    Thanks
    Sumit


  • Mike Wahler

    #2
    Re: dynamically instantiate a class


    "Sumit Nagpal" <sumit@noida.at renta.com> wrote in message
    news:2to780F22d nr4U1@uni-berlin.de...[color=blue]
    > Hi All,
    >
    > My application reads a 'Class' name (as a string) from a file at Run time.
    > Can i create an instance this Class ?[/color]

    Sure.

    std::string classname;
    std::ifstream instream("myfil e");
    instream >> classname;
    myClass *mc = 0;

    if(classname == "myClass")
    mc = new myClass;

    -Mike


    Comment

    • Phlip

      #3
      Re: dynamically instantiate a class

      Sumit Nagpal wrote:
      [color=blue]
      > My application reads a 'Class' name (as a string) from a file at Run time.
      > Can i create an instance this Class ?[/color]

      Look up Factory Pattern, and Prototype Pattern with Google.com

      --
      Phlip



      Comment

      • Pavel Vozenilek

        #4
        Re: dynamically instantiate a class


        "Sumit Nagpal" wrote:
        [color=blue]
        > My application reads a 'Class' name (as a string) from a file at Run time.
        > Can i create an instance this Class ?
        >[/color]
        You must add infrastructure: create object factory which
        takes string and outputs heap allocated class.

        /Pavel


        Comment

        • Michael Kurz

          #5
          Re: dynamically instantiate a class


          "Sumit Nagpal" <sumit@noida.at renta.com> schrieb im Newsbeitrag
          news:2to780F22d nr4U1@uni-berlin.de...[color=blue]
          > Hi All,
          >
          > My application reads a 'Class' name (as a string) from a file at Run time.
          > Can i create an instance this Class ?
          >[/color]
          No.

          Typically you would create a factory or at least a factory method,
          which creates an object based on the class name.

          Regards
          Michael


          Comment

          • Sumit Nagpal

            #6
            Re: dynamically instantiate a class

            Perhaps I didnt ask my question in properly.

            Say, I write some code in core.so and some other person writes plugin.so
            & plugin.txt
            plugin.txt has a string "MyClass"
            plugin.so has the definition of MyClass

            While writing core.so I dont know anything about MyClass.

            so there is no question of comparing it with something.


            please tell me if i am still unclear.

            Thanks
            Sumit



            Michael Kurz wrote:[color=blue]
            > "Sumit Nagpal" <sumit@noida.at renta.com> schrieb im Newsbeitrag
            > news:2to780F22d nr4U1@uni-berlin.de...
            >[color=green]
            >>Hi All,
            >>
            >>My application reads a 'Class' name (as a string) from a file at Run time.
            >>Can i create an instance this Class ?
            >>[/color]
            >
            > No.
            >
            > Typically you would create a factory or at least a factory method,
            > which creates an object based on the class name.
            >
            > Regards
            > Michael
            >
            >[/color]

            Comment

            • Sumit Nagpal

              #7
              Re: dynamically instantiate a class

              I certainly have to go for FACTORY method but in my case I need
              something more...
              I think 'dlsym' should work for me !



              Sumit Nagpal wrote:[color=blue]
              > Perhaps I didnt ask my question in properly.
              >
              > Say, I write some code in core.so and some other person writes plugin.so
              > & plugin.txt
              > plugin.txt has a string "MyClass"
              > plugin.so has the definition of MyClass
              >
              > While writing core.so I dont know anything about MyClass.
              >
              > so there is no question of comparing it with something.
              >
              >
              > please tell me if i am still unclear.
              >
              > Thanks
              > Sumit
              >
              >
              >
              > Michael Kurz wrote:
              >[color=green]
              >> "Sumit Nagpal" <sumit@noida.at renta.com> schrieb im Newsbeitrag
              >> news:2to780F22d nr4U1@uni-berlin.de...
              >>[color=darkred]
              >>> Hi All,
              >>>
              >>> My application reads a 'Class' name (as a string) from a file at Run
              >>> time.
              >>> Can i create an instance this Class ?
              >>>[/color]
              >>
              >> No.
              >>
              >> Typically you would create a factory or at least a factory method,
              >> which creates an object based on the class name.
              >>
              >> Regards
              >> Michael
              >>
              >>[/color][/color]

              Comment

              • Gianni Mariani

                #8
                Re: dynamically instantiate a class

                Sumit Nagpal wrote:[color=blue]
                > I certainly have to go for FACTORY method but in my case I need
                > something more...
                > I think 'dlsym' should work for me ![/color]

                Warning ... try to steer away from dlsym. This reqyures you to know
                what the mangling convention is - this is not portable.

                Austria C++ (Shameless plug) has a solution for you and it works with
                DLL's or DSO's.

                Below is an example.


                -------------- test code ------------------

                #include "interface. h"

                #include "at_factory .h"

                using namespace at;


                #include <iostream>
                #include <dlfcn.h>


                void Test( Interface * ptr )
                {
                if ( ! ptr )
                {
                std::cout << "There is no ptr\n";
                return;
                }

                std::cout << "Thingy() = " << ptr->Thingy() << "\n";
                std::cout << "Thingy1() = " << ptr->Thingy1() << "\n";
                std::cout << "Thingy2() = " << ptr->Thingy2() << "\n";

                bool is_del = false;

                ptr->MarkPtr( & is_del );

                delete ptr;

                std::cout << ( is_del ? "Deleted" : "Not Deleted" ) << "\n";

                }


                void testfactory()
                {


                Interface * ptr =
                FactoryRegister < Interface, DKy, Creator1P< Interface, DKy,
                const char * > >
                ::Get().Create( "ImplementorKEY " )( "contructor param" );

                Test( ptr );

                ptr =
                FactoryRegister < Interface, DKy, Creator2P< Interface, DKy,
                const char *, const char * > >
                ::Get().Create( "ImplementorKEY " )( "contructor param1",
                "contructor param2" );

                Test( ptr );
                }

                void loaddso()
                {
                if ( ! dlopen( "xxx_dso.so ", RTLD_LAZY ) )
                {
                std::cerr << "dlopen error is: " << dlerror();
                }
                }

                int main()
                {

                /* output should be :
                There is no ptr
                There is no ptr
                */

                testfactory();

                // load the objects ...
                loaddso();

                /*output should now be :
                Thingy() = contructor param
                Thingy1() =
                Thingy2() =
                Deleted
                Thingy() = contructor param1
                Thingy1() = contructor param2
                Thingy2() =
                Deleted
                */

                testfactory();

                }



                ------------------- interface.h -------------------------



                class Interface
                {

                public:

                virtual const char * Thingy() = 0;
                virtual const char * Thingy1() = 0;
                virtual const char * Thingy2() = 0;

                bool * mark_del;

                Interface()
                : mark_del( 0 )
                {
                }

                virtual ~Interface()
                {
                if ( mark_del )
                {
                * mark_del = true;
                }
                }

                void MarkPtr( bool * i_mark_del )
                {
                mark_del = i_mark_del;
                }

                virtual int ContructParamCo unt() = 0;

                };


                --------------- implementation code ---- xxx_dso.cpp ----------

                #include "interface. h"

                #include "at_factory .h"

                using namespace at;


                class Implementor
                : public Interface
                {

                public:

                virtual const char * Thingy()
                {
                return m_str;
                }

                virtual const char * Thingy1()
                {
                return m_str2;
                }

                virtual const char * Thingy2()
                {
                return m_str3;
                }

                Implementor( const char * str, const char * str2, const char *
                str3 )
                : m_str( str ),
                m_str2( str2 ),
                m_str3( str3 ),
                contruction_par ameter_count( 3 )
                {
                }

                Implementor( const char * str, const char * str2 )
                : m_str( str ),
                m_str2( str2 ),
                m_str3( "" ),
                contruction_par ameter_count( 2 )
                {
                }

                Implementor( const char * str )
                : m_str( str ),
                m_str2( "" ),
                m_str3( "" ),
                contruction_par ameter_count( 1 )
                {
                }

                Implementor()
                : m_str( "" ),
                m_str2( "" ),
                m_str3( "" ),
                contruction_par ameter_count( 0 )
                {
                }

                virtual int ContructParamCo unt()
                {
                return contruction_par ameter_count;
                }

                int contruction_par ameter_count;

                const char * m_str;
                const char * m_str2;
                const char * m_str3;
                };


                AT_MakeFactory0 P( "ImplementorKEY ", Implementor, Interface, DKy );
                AT_MakeFactory1 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                char * );
                AT_MakeFactory2 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                char *, const char * );
                AT_MakeFactory3 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                char *, const char *, const char * );

                Comment

                • Michael Kurz

                  #9
                  Re: dynamically instantiate a class


                  "Sumit Nagpal" <sumit@noida.at renta.com> schrieb im Newsbeitrag
                  news:2tocnnF21r nojU1@uni-berlin.de...[color=blue]
                  > Perhaps I didnt ask my question in properly.
                  >
                  > Say, I write some code in core.so and some other person writes plugin.so
                  > & plugin.txt
                  > plugin.txt has a string "MyClass"
                  > plugin.so has the definition of MyClass
                  >
                  > While writing core.so I dont know anything about MyClass.
                  >
                  > so there is no question of comparing it with something.
                  >
                  >[/color]

                  So If Iam right that *.so is a dynamic link library on linux (Iam more
                  familar with the windows stuff: DLL)
                  You need to export symbols, which can be used:

                  Thats how COM does it (roughly, adapted to your question):
                  - Define a Factory Interface (abtract base class), which is able to create
                  objects by a given class name and returns a pointer to the created object,
                  as you probably want to create different kinds of objects, of course all
                  objects created with one factory (factory interface) should share the
                  (abstract) BaseClass.

                  -Define an exported function within your *.so / *.dll file, which returns a
                  pointer to the factory.
                  (COM: CoGetClassObjec t), to make this compiler independent you could make
                  this function with C Linkage (extern "C")

                  If you want something like:
                  *.so contains a class, you only know the name nothing else about the class
                  and you want to create an instance without providing an Interface, well this
                  will not work with C++.



                  Regards
                  Michael


                  Comment

                  • Karl Heinz Buchegger

                    #10
                    Re: dynamically instantiate a class

                    Sumit Nagpal wrote:[color=blue]
                    >
                    > Perhaps I didnt ask my question in properly.
                    >
                    > Say, I write some code in core.so and some other person writes plugin.so
                    > & plugin.txt
                    > plugin.txt has a string "MyClass"
                    > plugin.so has the definition of MyClass
                    >
                    > While writing core.so I dont know anything about MyClass.[/color]

                    Right.

                    I would do it this way:
                    All your plugins contain one class, which represents the plugin.
                    All those classes are derived from a common base class. All the
                    core knows about is a collection of pointers to those in order
                    to route commands to them.
                    So how then is the real plugin object created?
                    Simple: Each plugin.so has a function 'Create' which creates
                    the real plugin object and returns a pointer to it. And the
                    plugin.so knows about its real class.

                    --
                    Karl Heinz Buchegger
                    kbuchegg@gascad .at

                    Comment

                    • Sumit Nagpal

                      #11
                      Re: dynamically instantiate a class

                      Yeah but if I do extern 'C' for that particular symbol, there wont be
                      any name mangling problem.

                      Thanks
                      Sumit Nagpal


                      Gianni Mariani wrote:[color=blue]
                      > Sumit Nagpal wrote:
                      >[color=green]
                      >> I certainly have to go for FACTORY method but in my case I need
                      >> something more...
                      >> I think 'dlsym' should work for me ![/color]
                      >
                      >
                      > Warning ... try to steer away from dlsym. This reqyures you to know
                      > what the mangling convention is - this is not portable.
                      >
                      > Austria C++ (Shameless plug) has a solution for you and it works with
                      > DLL's or DSO's.
                      >
                      > Below is an example.
                      >
                      >
                      > -------------- test code ------------------
                      >
                      > #include "interface. h"
                      >
                      > #include "at_factory .h"
                      >
                      > using namespace at;
                      >
                      >
                      > #include <iostream>
                      > #include <dlfcn.h>
                      >
                      >
                      > void Test( Interface * ptr )
                      > {
                      > if ( ! ptr )
                      > {
                      > std::cout << "There is no ptr\n";
                      > return;
                      > }
                      >
                      > std::cout << "Thingy() = " << ptr->Thingy() << "\n";
                      > std::cout << "Thingy1() = " << ptr->Thingy1() << "\n";
                      > std::cout << "Thingy2() = " << ptr->Thingy2() << "\n";
                      >
                      > bool is_del = false;
                      >
                      > ptr->MarkPtr( & is_del );
                      >
                      > delete ptr;
                      >
                      > std::cout << ( is_del ? "Deleted" : "Not Deleted" ) << "\n";
                      >
                      > }
                      >
                      >
                      > void testfactory()
                      > {
                      >
                      >
                      > Interface * ptr =
                      > FactoryRegister < Interface, DKy, Creator1P< Interface, DKy,
                      > const char * > >
                      > ::Get().Create( "ImplementorKEY " )( "contructor param" );
                      >
                      > Test( ptr );
                      >
                      > ptr =
                      > FactoryRegister < Interface, DKy, Creator2P< Interface, DKy,
                      > const char *, const char * > >
                      > ::Get().Create( "ImplementorKEY " )( "contructor param1",
                      > "contructor param2" );
                      >
                      > Test( ptr );
                      > }
                      >
                      > void loaddso()
                      > {
                      > if ( ! dlopen( "xxx_dso.so ", RTLD_LAZY ) )
                      > {
                      > std::cerr << "dlopen error is: " << dlerror();
                      > }
                      > }
                      >
                      > int main()
                      > {
                      >
                      > /* output should be :
                      > There is no ptr
                      > There is no ptr
                      > */
                      >
                      > testfactory();
                      >
                      > // load the objects ...
                      > loaddso();
                      >
                      > /*output should now be :
                      > Thingy() = contructor param
                      > Thingy1() =
                      > Thingy2() =
                      > Deleted
                      > Thingy() = contructor param1
                      > Thingy1() = contructor param2
                      > Thingy2() =
                      > Deleted
                      > */
                      >
                      > testfactory();
                      >
                      > }
                      >
                      >
                      >
                      > ------------------- interface.h -------------------------
                      >
                      >
                      >
                      > class Interface
                      > {
                      >
                      > public:
                      >
                      > virtual const char * Thingy() = 0;
                      > virtual const char * Thingy1() = 0;
                      > virtual const char * Thingy2() = 0;
                      >
                      > bool * mark_del;
                      >
                      > Interface()
                      > : mark_del( 0 )
                      > {
                      > }
                      >
                      > virtual ~Interface()
                      > {
                      > if ( mark_del )
                      > {
                      > * mark_del = true;
                      > }
                      > }
                      >
                      > void MarkPtr( bool * i_mark_del )
                      > {
                      > mark_del = i_mark_del;
                      > }
                      >
                      > virtual int ContructParamCo unt() = 0;
                      >
                      > };
                      >
                      >
                      > --------------- implementation code ---- xxx_dso.cpp ----------
                      >
                      > #include "interface. h"
                      >
                      > #include "at_factory .h"
                      >
                      > using namespace at;
                      >
                      >
                      > class Implementor
                      > : public Interface
                      > {
                      >
                      > public:
                      >
                      > virtual const char * Thingy()
                      > {
                      > return m_str;
                      > }
                      >
                      > virtual const char * Thingy1()
                      > {
                      > return m_str2;
                      > }
                      >
                      > virtual const char * Thingy2()
                      > {
                      > return m_str3;
                      > }
                      >
                      > Implementor( const char * str, const char * str2, const char *
                      > str3 )
                      > : m_str( str ),
                      > m_str2( str2 ),
                      > m_str3( str3 ),
                      > contruction_par ameter_count( 3 )
                      > {
                      > }
                      >
                      > Implementor( const char * str, const char * str2 )
                      > : m_str( str ),
                      > m_str2( str2 ),
                      > m_str3( "" ),
                      > contruction_par ameter_count( 2 )
                      > {
                      > }
                      >
                      > Implementor( const char * str )
                      > : m_str( str ),
                      > m_str2( "" ),
                      > m_str3( "" ),
                      > contruction_par ameter_count( 1 )
                      > {
                      > }
                      >
                      > Implementor()
                      > : m_str( "" ),
                      > m_str2( "" ),
                      > m_str3( "" ),
                      > contruction_par ameter_count( 0 )
                      > {
                      > }
                      >
                      > virtual int ContructParamCo unt()
                      > {
                      > return contruction_par ameter_count;
                      > }
                      >
                      > int contruction_par ameter_count;
                      >
                      > const char * m_str;
                      > const char * m_str2;
                      > const char * m_str3;
                      > };
                      >
                      >
                      > AT_MakeFactory0 P( "ImplementorKEY ", Implementor, Interface, DKy );
                      > AT_MakeFactory1 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                      > char * );
                      > AT_MakeFactory2 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                      > char *, const char * );
                      > AT_MakeFactory3 P( "ImplementorKEY ", Implementor, Interface, DKy, const
                      > char *, const char *, const char * );
                      >[/color]

                      Comment

                      • Sumit Nagpal

                        #12
                        Re: dynamically instantiate a class

                        You are right but I was talking about the situations where I'll have
                        multiple unkown plugins.
                        Now I have the solution for it 'dlsym' which will allow me to
                        instantiate all plugin classes with all plugin.so having 'Create' functions.

                        Thanks
                        Sumit


                        Karl Heinz Buchegger wrote:[color=blue]
                        > Sumit Nagpal wrote:
                        >[color=green]
                        >>Perhaps I didnt ask my question in properly.
                        >>
                        >>Say, I write some code in core.so and some other person writes plugin.so
                        >>& plugin.txt
                        >>plugin.txt has a string "MyClass"
                        >>plugin.so has the definition of MyClass
                        >>
                        >>While writing core.so I dont know anything about MyClass.[/color]
                        >
                        >
                        > Right.
                        >
                        > I would do it this way:
                        > All your plugins contain one class, which represents the plugin.
                        > All those classes are derived from a common base class. All the
                        > core knows about is a collection of pointers to those in order
                        > to route commands to them.
                        > So how then is the real plugin object created?
                        > Simple: Each plugin.so has a function 'Create' which creates
                        > the real plugin object and returns a pointer to it. And the
                        > plugin.so knows about its real class.
                        >[/color]

                        Comment

                        Working...