动态类加载的设计模式 [英] Design Pattern for Dynamic Class Loading

查看:69
本文介绍了动态类加载的设计模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,


如果这是这个问题的错误组,请道歉。我想

设计一个界面,对于自定义功能,客户端

用函数实现写一个新类然后把

作为配置参数或类的类的名称然后

主程序像模块一样加载新类,客户端可以现在使用新函数编写代码
。我想这个问题已经解决了之前已经解决过的问题,如果有的话,最好的办法是什么呢。


谢谢

Digz


例如:


我已经为他提供了

printInt.cc:

struct printInt {

void operator()(int i)

{Print(i); }


现在用户想要编写一个类并开始使用类中的实现



printDbl.cc这是

struct printDbl {

void operator()(double i)

{Print(i); }


int main()

{

Config * c = readConfig();

对于c-> classNames()中的名称:

加载(名称);


printDbl pd;

pd(1.0 );

}

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写道:
digz wrote:

你好,


如果这是这个问题的错误组,请道歉。我想

设计一个界面,对于自定义功能,客户端

用函数实现写一个新类然后把

作为配置参数或类的类的名称然后

主程序像模块一样加载新类,客户端可以现在使用新函数编写代码
。我想这个问题已经解决了之前已经解决过的问题,如果有的话,最好的办法是什么呢。


谢谢

Digz


例如:


我已经为他提供了

printInt.cc:

struct printInt {

void operator()(int i)

{Print(i); }


现在用户想要编写一个类并开始使用类中的实现



printDbl.cc这是

struct printDbl {

void operator()(double i)

{Print(i); }


int main()

{

Config * c = readConfig();

对于c-> classNames()中的名称:

加载(名称);


printDbl pd;

pd(1.0 );

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



加载是依赖操作系统实现的,所以你最好的选择是

寻求信息在各自的新闻组中。您正在寻找的关键字

是动态加载(dlload,LoadLibrary等)...


F

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

digz写道:
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 .



由于C ++是一种静态类型语言,编译时编译器需要知道类型
。您描述的大多数内容都可能是
,并且是用于
C ++编程的任何插件架构的基础。您可以查看Mozilla或任何其他具有插件的开源

项目,或者只是在有关该主题的书中写了

的项目。


提供你所要求的通常方法是在你的系统中指定一些

函数作为工厂。所有功能都是基于现有类(如''printInt'')结构,

构建的,并允许插件提供其实现*和*

必要的工厂函数,它实例化派生类,

返回指向基数的指针。系统然后将指针存储到基类的

,并且当虚函数(是的,运算符()需要

为虚拟时)被调用,自定义实现是

将被调用。


OOH,插件架构现在非常普遍,并在
$中描述b $ b很多地方(你可以在新闻档案中找到一些),OTOH,

它不是一个简单的10行编码练习,所以,恕我直言它不会使/>
感觉花时间在这里描述它。我强烈建议你在可用的信息来源中查看
,网页应该是第一个要查看的内容。

Since C++ is a statically typed language, the types need to be known to
the compiler at the compile-time. Most of what you describe is possible
and serves as the foundation of any plug-in architecture programmed in
C++. You can probably look into Mozilla or any other open-source
projects that have plug-ins, or just read about them in books that have
been written on the subject.

The usual way to provide what you''re asking about is to designate some
function[s] in your system to be "factories". All the functionality is
structured based on the existing classes (like your ''printInt'') struct,
and the plug-ins are allowed to provide their implementation *and* the
necessary factory function which instantiates the derived class and
returns the pointer to the base. The system then stores the pointer to
the base class and when the virtual function (yes, the operator() needs
to be ''virtual'' in that case) is called, the custom implementation is
going to be invoked.

OOH, plug-in architectures are very common nowadays and described in
many places (and you can probably find some in the news archives), OTOH,
it''s not a simple 10-line coding exercise, so, IMHO it does not make
sense to spend time describing it here. I strongly recommend you to
look in the available information sources, the web should be the first
thing to look through.


>

谢谢

Digz


例如:


我已经为他提供了

printInt.cc:

struct printInt {

void operator()(int i)

{Print(i); }


现在用户想要编写一个类并开始使用类中的实现



printDbl.cc这是

struct printDbl {

void operator()(double i)

{Print(i); }


int main()

{

Config * c = readConfig();

对于c-> classNames()中的名称:

加载(名称);


printDbl pd;

pd(1.0 );

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



V

-

请删除资金' 'A'在通过电子邮件回复时

我没有回复最热门的回复,请不要问

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


digz< Di ******** @ gmail.comwrites:
digz <Di********@gmail.comwrites:

你好,


如果这是道歉是这个问题的错误组。我想

设计一个界面,对于自定义功能,客户端

用函数实现写一个新类然后把

作为配置参数或类的类的名称然后

主程序像模块一样加载新类,客户端可以现在使用新函数编写代码
。我想这个问题已经解决了之前已经解决过的问题,如果有的话,最好的办法是什么呢。


谢谢

Digz


例如:


我已经为他提供了

printInt.cc:

struct printInt {

void operator()(int i)

{Print(i); }


现在用户想要编写一个类并开始使用类中的实现



printDbl.cc这是

struct printDbl {

void operator()(double i)

{Print(i); }


int main()

{

Config * c = readConfig();

对于c-> classNames()中的名称:

加载(名称);


printDbl pd;

pd(1.0 ); $

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



最简单的方法是使用lisp。你真的为什么用这种方式抨击你的大脑?只要使用lisp,就没有什么可以让用户在正在运行的lisp程序中添加函数了。
http://common-lisp.net/

否则,用更动态的方式做起来会更容易语言,

a程序时,你可以更正一个类,并重新加载它。

当然,你可以动态加载类或者

Objective-C程序中的部分类随意,您甚至可以在旧代码之前发送未知的消息(使用-perform:方法a

计算选择器)。
http://developer.apple.com/documenta...nkElementID_76


在C ++中,这可能是可能的,但只能通过虚拟方法(或通过

正常的C类函数)。


它不会帮助用户给他提供printInt。您将获得

为他提供超类和工厂入口点:


类PrintStuff {

public:

virtual~PrintStuff(){}

virtual void setArgument(int anInt)= 0;

virtual void setArgument(double aDouble) = 0;

virtual void setArgument(std :: string aString)= 0;

虚拟doIt(void)= 0;


};


typedef PrintStuff *(* FactoryFun)(无效);

extern PrintStuff * factory(void);


然后他将实现一个具体的子类,并为工厂提供一个实现:

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(aS tring); s>> value;}

虚拟doIt(void){std :: cout<<"我的值是"<<<<<< std :: end ;}


};


PrintStuff * factory(无效){

return(new PrintDouble()) ;

}

编译成可动态加载的库,这可能是加载到正在运行的C ++程序中的
,然后可以:


int main(void){

Config * c = new Config(" myapp.conf");

FactoryFun factory = loadAndFindSymbol(c-> libraryName()," factory");

PrintStuff * obj = factory();

obj-> setArgument(42) ;

obj-> doIt();

}


实现loadAndFindSymbol,在unix系统上看看dlopen ,

dlsym,dlclose。名称损坏可能会有一些困难

,也许最好声明:

externC{

extern PrintStuff *工厂(无效);

}

-

__Pascal Bourguignon__


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/documenta...nkElementID_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__


这篇关于动态类加载的设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆