这是我正在尝试做的事情:
我正在开发一个支持插件的跨平台IDE(Linux和Windows)。我需要使用与Eclipse提供的适配器框架相似的适配器框架来支持可扩展性。有关更多详细信息,请参见here,但是基本上我需要以下内容:
让Adaptee
和Adapted
是完全不相关的类,它们已经存在并且不允许以任何方式进行更改。我想创建一个具有方法的AdapterManager
类
template <class Adaptee, class Adapted> Adapted* adapt( Adaptee* object);
给定
Adapted
实例,它将创建Adaptee
实例。如何精确创建实例取决于适配器功能,该功能必须向AdapterManager
注册。每个新插件都应能够为任意类型提供适配器功能。这是我对可能的解决方案以及为何不起作用的想法:
type_info
类提供了hash_code()
方法,该方法为程序中的每种类型返回唯一的整数。参见here。因此,AdapterManager
可以仅包含一个映射,该映射给出了Adaptee和Adapter类的哈希码,从而返回指向适配器函数的函数指针。这使得上面的adapt()
函数的实现很简单:template <class Adaptee, class Adapted> Adapted* AdapterManager::adapt( Adaptee* object)
{
AdapterMapKey mk( typeid(Adapted).hash_code(), typeid(Adaptee).hash_code());
AdapterFunction af = adapterMap.get(mk);
if (!af) return nullptr;
return (Adapted*) af(object);
}
任何插件都可以通过简单地将附加功能插入 map 来轻松扩展框架。还要注意,如果存在使用
AdapterManager
注册的相应适配器功能,则无论是谁注册的,任何插件都可以尝试使任何类适应其他任何类并成功。 type_info
结构的两个单独实例以及潜在的hash_code()
结果不同,这将破坏上面的机制。从一个插件注册的适配器功能可能并不总是在另一个插件中起作用。 问题:
更新1:
该项目将Qt框架用于许多事情,包括插件基础结构。 Qt确实有助于跨平台开发。如果您知道针对该问题的Qt特定解决方案,也欢迎您。
更新2:
n.m.的评论使我意识到,我只在理论上了解该问题,而没有实际测试过。因此,我使用以下定义在Windows和Linux上进行了一些测试:
template <class T>
class TypeIdTest {
public:
virtual ~TypeIdTest() {};
static int data;
};
template <class T> int TypeIdTest<T>::data;
此类在两个不同的共享库/DLL中以T = int实例化。这两个库都在运行时显式加载。这是我发现的:
在Linux中,一切正常:
typeid
返回的对象位于同一地址。 在Windows中,两个实例化在“某种程度上”是不同的:
typeid
在不同地址返回type_info
对象。但是,当使用==
测试时,这些对象是相等的。相应的哈希码也相等。在Windows上,似乎类型之间的相等性是使用类型的名称建立的-这很有意义。到现在为止还挺好。 dynamic_cast
将TypeIdTest
的实例向下转换为跨共享库边界的派生类型。 data
的副本。这可能会导致很多问题,并且基本上不允许模板类中的静态字段。 总体而言,似乎即使在Windows中,情况也没有我想像的那么糟糕,但是由于模板实例化仍然使用不同的vtable和静态存储,因此我仍然不愿意使用这种方法。有谁知道如何避免这个问题?我没有找到任何解决方案。
最佳答案
我认为Boost Extension完全可以解决此问题域:
(in preparation for this library's submission to Boost for review)
特别是您可能会对作者在this blog post: "Resource Management Across DLL Boundaries中写的内容感兴趣:
RTTI does not always function as expected across DLL boundaries. Check out the type_info classes to see how I deal with that.
我不确定他的解决方案是否确实可靠,但是他确实曾考虑过这个想法。实际上,您可以尝试使用Boost扩展的一些示例,您可能想要使用它。
关于c++ - 如何在可在Linux和Windows上运行的C++中实现适配器框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9275065/