Design Pattern for Dynamic Class Loading

Discussion in 'C++' started by digz, Jul 29, 2008.

  1. digz

    digz Guest

    Hello,

    Apologies if this is the wrong group for this question. I want to
    design an interface , where for a custom functionality , the client
    writes a new class with the function implementation and then puts the
    name of the Class as a configuration parameter or something and then
    the main program loads the new class like a module and the client can
    now write code using the new Functions. I suppose this problem has
    been solved before , if so what is the best way to do this .

    Thanks
    Digz

    Example :

    I have already provided him with
    printInt.cc :
    struct printInt {
    void operator ()(int i)
    { Print(i); }

    Now the user wants to write a class and start using the implementation
    in the class
    printDbl.cc which is
    struct printDbl{
    void operator ()(double i)
    { Print(i); }

    int main()
    {
    Config* c = readConfig();
    For name in c->classNames():
    Load( name ) ;

    printDbl pd;
    pd(1.0);
    }
    digz, Jul 29, 2008
    #1
    1. Advertising

  2. digz

    Fei Liu Guest

    digz wrote:
    > Hello,
    >
    > Apologies if this is the wrong group for this question. I want to
    > design an interface , where for a custom functionality , the client
    > writes a new class with the function implementation and then puts the
    > name of the Class as a configuration parameter or something and then
    > the main program loads the new class like a module and the client can
    > now write code using the new Functions. I suppose this problem has
    > been solved before , if so what is the best way to do this .
    >
    > Thanks
    > Digz
    >
    > Example :
    >
    > I have already provided him with
    > printInt.cc :
    > struct printInt {
    > void operator ()(int i)
    > { Print(i); }
    >
    > Now the user wants to write a class and start using the implementation
    > in the class
    > printDbl.cc which is
    > struct printDbl{
    > void operator ()(double i)
    > { Print(i); }
    >
    > int main()
    > {
    > Config* c = readConfig();
    > For name in c->classNames():
    > Load( name ) ;
    >
    > printDbl pd;
    > pd(1.0);
    > }

    Load is implemented operating system dependent, so your best bet is to
    seek info in their respective newsgroups. The keyword you are looking
    for is dynamic loading (dlload, LoadLibrary etc)...

    F
    Fei Liu, Jul 29, 2008
    #2
    1. Advertising

  3. digz <> writes:

    > Hello,
    >
    > Apologies if this is the wrong group for this question. I want to
    > design an interface , where for a custom functionality , the client
    > writes a new class with the function implementation and then puts the
    > name of the Class as a configuration parameter or something and then
    > the main program loads the new class like a module and the client can
    > now write code using the new Functions. I suppose this problem has
    > been solved before , if so what is the best way to do this .
    >
    > Thanks
    > Digz
    >
    > Example :
    >
    > I have already provided him with
    > printInt.cc :
    > struct printInt {
    > void operator ()(int i)
    > { Print(i); }
    >
    > Now the user wants to write a class and start using the implementation
    > in the class
    > printDbl.cc which is
    > struct printDbl{
    > void operator ()(double i)
    > { Print(i); }
    >
    > int main()
    > {
    > Config* c = readConfig();
    > For name in c->classNames():
    > Load( name ) ;
    >
    > printDbl pd;
    > pd(1.0);
    > }



    The easiest way to do that would be to use lisp. Really why are you
    bashing your brains this way? Just use lisp, there's nothing
    simplier to let the user add functions to a running lisp program.
    http://common-lisp.net/



    Otherwise, it would be easier to do it with a more dynamic language,
    like Objective-C. Apple's Xcode allows you to do that, when debugging
    a program, you can correct a class, and reload it.
    Of course, you can dynamically load classes or parts of classes in an
    Objective-C program at will, and you can even send messages that were
    unknown before hand from old code (using a -perform: method with a
    computed selector).
    http://developer.apple.com/document...f/doc/uid/TP40002974-CH4-DontLinkElementID_76



    In C++, that may be possible, but only thru virtual methods (or thru
    normal C-like functions).

    It won't help the "user" to provide him with printInt. You will have
    to provide him with a superclass and a factory entry point:

    class PrintStuff {
    public:
    virtual ~PrintStuff(){}

    virtual void setArgument(int anInt)=0;
    virtual void setArgument(double aDouble)=0;
    virtual void setArgument(std::string aString)=0;
    virtual doIt(void)=0;

    };

    typedef PrintStuff* (*FactoryFun)(void);
    extern PrintStuff* factory(void);



    Then he will implement a concrete subclass, and provide an implementation for the factory:


    class PrintDouble:public PrintStuff {
    double value;
    public:
    PrintDouble():value(0.0d0){}
    virtual ~PrintDouble(){}

    virtual void setArgument(int anInt){value=anInt;}
    virtual void setArgument(double aDouble){value=aDouble;}
    virtual void setArgument(std::string aString){std::istringstream s(aString);s>>value;}
    virtual doIt(void){std::cout<<"My value is "<<value<<std::end;}

    };

    PrintStuff* factory(void){
    return(new PrintDouble());
    }


    Well compiled as a dynamically loadable library, this could could be
    loaded into your running C++ program, that could then do:

    int main(void){
    Config* c=new Config("myapp.conf");
    FactoryFun factory=loadAndFindSymbol(c->libraryName(),"factory");
    PrintStuff* obj=factory();
    obj->setArgument(42);
    obj->doIt();
    }

    to implement loadAndFindSymbol, on unix systems have a look at dlopen,
    dlsym, dlclose. There may be some difficulties with name mangling
    too, perhaps it would be best to declare:
    extern "C"{
    extern PrintStuff* factory(void);
    }


    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Jul 29, 2008
    #3
  4. digz

    mlimber Guest

    On Jul 29, 9:54 am, digz <> wrote:
    > Apologies if this is the wrong group for this question. I want to
    > design an interface , where for a custom functionality , the client
    > writes a new class with the function implementation and then puts the
    > name of the Class as a configuration parameter or something and then
    > the main program loads the new class like a module and the client can
    > now write code using the new Functions. I suppose this problem has
    > been solved before , if so what is the best way to do this .


    In addition to what Victor said, you might want to check out object
    factories in _Modern C++ Design_ by Alexandrescu. They provide a
    mechanism to generate an object from an identifier like an enum, int,
    or string.

    Here's a preview of the MC++D chapter on the topic (pay to get the
    whole thing):

    http://safari.informit.com/0201704315/ch08

    And here's the latest code from the library that developed out of that
    book:

    http://loki-lib.sourceforge.net/index.php?n=Pattern.FactoryMethod

    Cheers! --M
    mlimber, Jul 29, 2008
    #4
  5. digz

    mlimber Guest

    On Jul 29, 10:56 am, (Pascal J. Bourguignon)
    wrote:
    > The easiest way to do that would be to use lisp.  Really why are you
    > bashing your brains this way?  Just use lisp, there's nothing
    > simplier to let the user add functions to a running lisp program.


    That's only the easiest way if (a) the OP and his/her customer already
    know Lisp, (b) the program s/he already has running could easily be
    converted to Lisp, (c) said program would be fully functional and fast
    enough in Lisp, and (d) the customer would accept a Lisp project,
    which the customer will be maintaining and adding to.

    In short, changing languages is not a trivial decision, and suggesting
    it as the simplest and easiest way to solve this (or most any real-
    world programming problem) is dubious at best.

    Cheers! --M
    mlimber, Jul 29, 2008
    #5
  6. mlimber <> writes:

    > On Jul 29, 10:56 am, (Pascal J. Bourguignon)
    > wrote:
    >> The easiest way to do that would be to use lisp.  Really why are you
    >> bashing your brains this way?  Just use lisp, there's nothing
    >> simplier to let the user add functions to a running lisp program.

    >
    > That's only the easiest way if (a) the OP and his/her customer already
    > know Lisp, (b) the program s/he already has running could easily be
    > converted to Lisp, (c) said program would be fully functional and fast
    > enough in Lisp, and (d) the customer would accept a Lisp project,
    > which the customer will be maintaining and adding to.
    >
    > In short, changing languages is not a trivial decision, and suggesting
    > it as the simplest and easiest way to solve this (or most any real-
    > world programming problem) is dubious at best.
    >
    > Cheers! --M


    (a) isn't lisp taught in all CS universities?
    (b) Lisp is Turing-complete.
    (c) Lisp is faster than C++. http://www.lrde.epita.fr/~didier/research/verna.06.imecs.pdf
    (d) customers don't mind the language, they want the job done.

    ;-P


    Sorry, I though it was a technical question.

    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Jul 29, 2008
    #6
  7. digz

    mlimber Guest

    On Jul 29, 11:39 am, (Pascal J. Bourguignon)
    wrote:
    > (a) isn't lisp taught in all CS universities?


    Doubtful, and in any case many programs are written by non-CS majors
    (think math, physics, chemistry, biology, engineering, etc.).

    > (b) Lisp is Turing-complete.


    See Pete's response.

    > (c) Lisp is faster than C++.http://www.lrde.epita.fr/~didier/research/verna.06.imecs.pdf


    I don't dispute that in some applications it may be (even when one
    factors in development and maintenance time), but I highly doubt it in
    general -- hence my "if".

    > (d) customers don't mind the language, they want the job done.


    That depends on the customer. Some won't care, but some will. One of
    my company's customers takes over the maintenance of the source code
    as well as the executables when the project is complete, and they do
    care what language is used. Indeed, I'd bet you donuts to dollars that
    we wouldn't have won the contract if we had said we were going to do
    it in Lisp (even worse would be to suggest the language change mid-
    stream!). There's simply not as much industry support for it.

    > Sorry, I though it was a technical question.


    It was. I'm just saying your solution was not nearly as practical or
    simple as you made it out to be.

    Cheers! --M
    mlimber, Jul 29, 2008
    #7
  8. Pete Becker <> writes:

    > On 2008-07-29 11:39:04 -0400, (Pascal
    > J. Bourguignon) said:
    >
    >> mlimber <> writes:
    >>
    >>> On Jul 29, 10:56 am, (Pascal J. Bourguignon)
    >>> wrote:
    >>>> The easiest way to do that would be to use lisp.  Really why are you
    >>>> bashing your brains this way?  Just use lisp, there's nothing
    >>>> simplier to let the user add functions to a running lisp program.
    >>> That's only the easiest way if (a) the OP and his/her customer
    >>> already
    >>> know Lisp, (b) the program s/he already has running could easily be
    >>> converted to Lisp, (c) said program would be fully functional and fast
    >>> enough in Lisp, and (d) the customer would accept a Lisp project,
    >>> which the customer will be maintaining and adding to.
    >>> In short, changing languages is not a trivial decision, and
    >>> suggesting
    >>> it as the simplest and easiest way to solve this (or most any real-
    >>> world programming problem) is dubious at best.
    >>> Cheers! --M

    >> (b) Lisp is Turing-complete.

    >
    > So is a Turing machine, but that doesn't mean that it's easy to
    > convert existing code to it.


    Yep, you don't seem to recognize the irony...
    (Hint: Lisp is more powerfull and more expressive).

    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Jul 30, 2008
    #8
  9. Pascal J. Bourguignon a écrit :
    > Pete Becker <> writes:
    >> On 2008-07-29 11:39:04 -0400, (Pascal
    >> J. Bourguignon) said:
    >>> (b) Lisp is Turing-complete.

    >> So is a Turing machine, but that doesn't mean that it's easy to
    >> convert existing code to it.

    >
    > Yep, you don't seem to recognize the irony...
    > (Hint: Lisp is more powerfull and more expressive).


    That doesn't matter. Lisp is a functional programming language which
    means statistics are against him in industry world (except for some
    project like Yahoo system written in LISP IIRC and few others).

    There is some talk about Erlang which is surfing on the parallelization
    fashion. But, in the end, number will tell and imperative language
    programmers have a big demographic advance.

    Coming back to the subject, switching to another language for one
    feature (dynamic loading) is a bit overkill. There are some framework
    and libraries that can leverage this effort in C++; XPCOM is an example
    but google gives other results.

    Notably Boost.Plugin(abandoned?) and Boost.Extension/Boost.Reflection.
    http://boost-extension.blogspot.com/

    --
    Michael
    Michael DOUBEZ, Jul 30, 2008
    #9
  10. "Pascal J. Bourguignon" <> wrote in message
    news:...
    > Pete Becker <> writes:
    >
    >> On 2008-07-29 11:39:04 -0400, (Pascal
    >> J. Bourguignon) said:
    >>
    >>> mlimber <> writes:
    >>>
    >>>> On Jul 29, 10:56 am, (Pascal J. Bourguignon)
    >>>> wrote:
    >>>>> The easiest way to do that would be to use lisp. Really why are you
    >>>>> bashing your brains this way? Just use lisp, there's nothing
    >>>>> simplier to let the user add functions to a running lisp program.
    >>>> That's only the easiest way if (a) the OP and his/her customer
    >>>> already
    >>>> know Lisp, (b) the program s/he already has running could easily be
    >>>> converted to Lisp, (c) said program would be fully functional and fast
    >>>> enough in Lisp, and (d) the customer would accept a Lisp project,
    >>>> which the customer will be maintaining and adding to.
    >>>> In short, changing languages is not a trivial decision, and
    >>>> suggesting
    >>>> it as the simplest and easiest way to solve this (or most any real-
    >>>> world programming problem) is dubious at best.
    >>>> Cheers! --M
    >>> (b) Lisp is Turing-complete.

    >>
    >> So is a Turing machine, but that doesn't mean that it's easy to
    >> convert existing code to it.

    >
    > Yep, you don't seem to recognize the irony...
    > (Hint: Lisp is more powerfull and more expressive).


    Hint: My TOP-SECRET programming language `ZZ' is WAY "FASTER" than LISP
    could ever even dream about being!


    BTW, do you want some of my chlorpromazine hci? Only then can you
    efficiently can join the lang warz!!


    WEEEEEEEEEEEEEEE!!!!!!
    Chris M. Thomasson, Jul 30, 2008
    #10
  11. digz

    mmirold Guest

    On Jul 29, 3:54 pm, digz <> wrote:
    > Hello,
    >
    > Apologies if this is the wrong group for this question. I want to
    > design an interface , where for a custom functionality , the client
    > writes a new class with the function implementation and then puts the
    > name of the Class as a configuration parameter or something and then
    > the main program loads the new class like a module and the client can
    > now write code using the new Functions. I suppose this problem has
    > been solved before , if so what is the best way to do this .


    Hi Digz,

    not sure if that is exactly what you are need, but take
    a look at:

    D.Schmidt et al.: Pattern-oriented Software Architecture Vol. 2
    (Patterns
    for Concurrent and Networked Objects)

    They present a pattern called "Component Configurator" which is
    introduced
    as follows:

    "The Component Configurator design pattern allows an application to
    link
    and unlink its component implementations at run-time without having to
    modify, recompile or statically relink the application. [...]"

    It seems that Schmidt put some effort in abstracting low-level
    details about opening DLLs/.so etc.

    Regards,
    Michael
    mmirold, Aug 8, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sunny
    Replies:
    1
    Views:
    461
    Salt_Peter
    Dec 7, 2006
  2. Bartholomew Simpson

    class design/ design pattern question

    Bartholomew Simpson, Jun 12, 2007, in forum: C++
    Replies:
    2
    Views:
    447
    Daniel T.
    Jun 12, 2007
  3. Pallav singh
    Replies:
    0
    Views:
    354
    Pallav singh
    Jan 22, 2012
  4. Pallav singh
    Replies:
    0
    Views:
    399
    Pallav singh
    Jan 22, 2012
  5. Pallav singh
    Replies:
    1
    Views:
    448
    Peter Remmers
    Jan 22, 2012
Loading...

Share This Page