我们有一个由应用程序中的一些共享库构成的插件,我们需要在应用程序运行时更新它。出于性能原因,我们在卸载旧插件之前加载并开始使用新插件,并且只有当所有线程都使用旧插件完成后,我们才卸载它。由于新插件和旧插件的库具有相同的符号,我们dlopen()
with RTLD_LOCAL
。如果我们不意外地从内部函数调用新插件来调用旧插件中的符号。
该插件的一个库可以dynamic_cast()
到由插件的另一个库创建的对象。这适用于 HP-UX、AIX、Solaris 和 Windows,但不适用于 Linux。据我所知,这是因为所有这些操作系统(编译器)都使用类的名称来比较类型(在dynamic_cast()
)但 Linux 使用名称字符串地址来进行此比较(以提高性能),并且由于每个库都有自己的type_info
对象(因为它加载了RTLD_LOCAL
)地址不同,因此相等的类型似乎不等于dynamic_cast()
.
有没有办法执行以下操作之一:
- 仅制作
type_info
对象被加载就像RTLD_GLOBAL
被提供。
- 让编译器使用类名比较而不是
type_info
用于比较类型之间的地址。
?我们使用的编译器是:
$ icpc -V
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
好吧,我们最终所做的就是解决这个问题。
我们添加到了我们想要的类中dynamic_cast()
两个静态函数:
static MyClass* doNew();
static MyClass* doDynCast(MyBase*);
这些是在 cpp 文件中实现的,该文件保留了new
, the dynamic_cast()
和type_info
对象在同一个库中,从而使dynamic_cast()
解决这个问题。
这个解决方案对于我们的具体情况来说已经足够了,但如果有人有更通用的解决方案,我们将受到欢迎。
我们发现的另一个选择是将类的所有实现放在 cpp 文件中,这使得typeinfo
符号仅存在于一个库中,所有其他库仅引用它。这会导致成功dynamic_cast()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)