Linux上的RTLD_LOCAL和dynamic_cast [英] RTLD_LOCAL and dynamic_cast on Linux

查看:310
本文介绍了Linux上的RTLD_LOCAL和dynamic_cast的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个由应用程序中的几个共享库构成的插件,我们需要在应用程序运行时对其进行更新.出于性能原因,我们在卸载旧插件之前先加载并开始使用新插件,只有在使用旧插件完成所有线程的情况下,我们才卸载它.由于新插件和旧插件的库中具有相同的符号,因此我们将dlopen()RTLD_LOCAL相同.如果我们不希望新的插件从内部函数偶然调用到旧插件的符号.

We have a plugin that is constructed of a few shared libraries in our application that we need to update while the application is running. For performance reasons we load and start using the new plugin before unloading the old plugin and only when all threads are done using the old plugin we unload it. Since the libraries of the new plugin and the old plugin have the same symbols in them we dlopen() with RTLD_LOCAL. If we don't the new plugin call from internal functions by accident to symbols from the old plugin.

插件的一个库对由插件的另一个库创建的对象执行dynamic_cast().这适用于HP-UX,AIX,Solaris和Windows,但不适用于Linux.据我了解,这是因为所有这些操作系统(编译器)都使用类的名称来比较类型(在dynamic_cast()中),但是Linux使用名称字符串地址来进行此比较(以提高性能),并且由于每个库有一个自己的type_info对象(因为它已经加载了RTLD_LOCAL),所以地址是不同的,因此相等的类型似乎不等于dynamic_cast().

One library of the plugin does dynamic_cast() to an object that was created by another library of the plugin. This works on HP-UX, AIX, Solaris and Windows but not on Linux. As far as I can understand this is because all these OSs (compliers) use the name of the class to compare types (in the dynamic_cast()) but Linux uses name strings addresses to do this comparison (to improve performance) and since each library has its own type_info object (since it was loaded with RTLD_LOCAL) the addresses are different and therefore equal types seems to be non equal to the dynamic_cast().

是否可以执行以下任一操作:

Is there a way to do one of the following:

  • 仅加载type_info个对象,就像提供了RTLD_GLOBAL一样.
  • 让编译器使用类名比较而不是type_info地址来在类型之间进行比较.
  • Make only the type_info objects be loaded as if RTLD_GLOBAL was supplied.
  • Make the compiler use class name comparison instead of type_info addresses for comparing between types.

?我们正在使用的编译器是:

? The compiler we are using is:

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

推荐答案

好吧,我们最终要做的就是解决该问题.

Ok, what we finally did is kind of worked around the problem.

我们在要dynamic_cast()的类中添加了两个静态函数:

We added to the classes that we want to dynamic_cast() two static functions:

static MyClass* doNew();
static MyClass* doDynCast(MyBase*);

这些是在cpp文件中实现的,该文件将newdynamic_cast()type_info对象保留在同一库中,从而使dynamic_cast()可以解决此问题.

These were implemented in the cpp file which kept the new, the dynamic_cast() and the type_info object in the same lib and thus making the dynamic_cast() work around the problem.

对于我们的特定情况,此解决方案就足够了,但是如果有人有更通用的解决方案,它将受到欢迎.

This solution was enough for our specific case but if anyone has a more general solution it will be welcomed.

我们发现的另一种选择是将类的所有实现都放入cpp文件中,这使得typeinfo符号仅出现在一个库中,而所有其他库仅引用它.这将导致成功dynamic_cast().

Another option that we found is to put all the implementation of the class in the cpp file which make the typeinfo symbol be present only in one library and all other libraries reference it only. This results in a successful dynamic_cast().

这篇关于Linux上的RTLD_LOCAL和dynamic_cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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