Design Pattern for Dynamic Class Loading

D

digz

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);
}
 
F

Fei Liu

digz said:
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
 
P

Pascal J. Bourguignon

digz said:
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);
}
 
M

mlimber

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
 
M

mlimber

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
 
P

Pascal J. Bourguignon

mlimber said:
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.
 
M

mlimber

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

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
 
P

Pascal J. Bourguignon

Pete Becker said:
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).
 
M

Michael DOUBEZ

Pascal J. Bourguignon a écrit :
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/
 
C

Chris M. Thomasson

Pascal J. Bourguignon said:
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!!!!!!
 
M

mmirold

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top