ClassLoader使用

ClassLoader手册.
------------------

目标DLLs应该导出一个名叫GetClassObject的函数,使用C语言链接。

如下:

在头文件中

extern "C" {
     IClassFactory* GetClassObject();
}

在源代码文件中:

extern "C" {
 IClassFactory* GetClassObject()
 {
      return new ExampleFactory();
 }
}

工厂应该从IClassFactory这个抽象类继承,必须实现来自IUnknown接口QueryInterface方法,AddRef和Release方法已经默认提供了实现。

 

CLSID类提供了用于访问标识对像的GUIDs。这个类可以通过C或C++字符串进行初始化。这个字符串可以是任何形式的,但基于系统正常运行的考虑,它们必须是唯一的。classloader库使用"ClassLoader::ExampleObject"格式的字符串,这里ClassLoader看起来就像ExampleObject接口的命名空间似的。你还可以同时提供附加的版本信息,这样做不是必须的。这样做建议的语法是:"ClassLoader::ExampleObject@1.0"

 

每一个从IUnknown继承进而实现了QueryInterface接口的类都应该定义它自己的CLSID,如果它是有用这种方式的话。

 

ConfigureClassLoader是非常有用的类提供者。它雇用ClassLoader帮它完成这项工作,但是也从IDynamicClassLoader继承其接口。它需要xml文件的路径作为其构造函数的参数。这是用来将CLSIDs映射到sonames(用于dlopen的共享库名字)
 

使用用库来加载对象:

你的程序需要为你想加载的外部库的每种类型的对象定义"一个"抽象基类。这些库需要和你的源代码一起编译,并且安装在一个可供动态加载器访问的目录:/usr/lib,/usr/local/lib或者在/etc/ld.so.conf中的文件夹列表中的任意一个,或者在LD_LIBRARY_PATH环境变量中的文件夹中(如果你这样用的话,你必须在程序每一次运行之前都要设置它)

 

(什么情况下你可以用类加载器)

如果你已经用CLSID对要加载的动态库名作了硬编码了,或者你已经有单独的方法去发现他们(CLSID和soname的对应关系),你就可以不用创建你自己的类加载器了。这时可以直接使用ClassLoader对象:

MyClass *obj;

ClassLoader *cl = new ClassLoader();
IClassFactory *cf = cl->GetClassObject( (string)soname );

int result = cf->CreateInstance( (CLSID)clsid, &obj );

.....

obj->Release();
delete cl; 
delete cf;

然而使用类加载器的最佳方法是通过ConfigureClassLoader,像这样:

MyClass *obj;

ConfiguredClassLoader *ccl = new ConfiguredClassLoader( (string)xml_file_path );
/* this causes the xml file to be parsed 
 * and the mapping from CLSIDs to sonames to be created
 */
IClassFactory *cf = ccl->GetClassObject( (CLSID)clsid, &obj );
int result = cf->CreateInstance( (CLSID)clsid, &obj );

etc.

如果你想使用曾经是唯一的方式创建一个单独的对象。你可以通过ClassLoader和ConfiguredClassLoader提供的快捷方式来实现:

ClassLoader *cl = new ClassLoader();
int result = cl->CreateInstance( soname, clsid, (void**)&obj );
// check result
// use `obj'

类似地:

ConfiguredClassLoader *ccl = new ConfiguredClassLoader( xml_file_path );
int result = ccl->CreateInstance( clsid, (void**)&obj );

 

请注意,这样做时其实是隐式地创建一个工厂对象,接着创建了你需要的对象,然后销毁工厂对象。不要使用这种方法创建大量的类似对象--这是很消耗cpu时间的。建议的用法是,使用上面的方法创建一次工厂对象,然后使用它创建尽可能多的对象。

 

查看docs/classloader.dtd和docs/sample.xml学习如何创建一个有效的XML配置文件;同时看一下示例文件夹下的示例程序和库。它们展示了本文档所描述的技术。

 

bugs和设计缺陷总是在所难免,但请反馈给我,这样我可以进一步的完善这段代码。

Chris Dawes, cmsd2@cam.ac.uk

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值