模块和类处理(动态链接)
Module and classes handling (dynamic linking)
遇到一点问题,我正在寻找最好的解决方案概念/理论。
我有一个系统需要使用对象。系统使用的每个对象都有一个已知的接口,可能作为抽象类实现。这些接口在构建时是已知的,并且不会更改。要使用的确切实现将有所不同,我不知道提前什么模块将提供它。唯一的保证是他们会提供接口。类名和模块(DLL)来自配置文件或可以通过编程方式更改。
现在,我已经使用一个相对简单的系统设置了所有这些,设置如下(重写伪代码,只是为了显示基本内容):struct ClassID
{
Module * module;
int number;
};
class Module
{
HMODULE module;
function<void * (int)> * createfunc;
static Module * Load(String filename);
IObject * CreateClass(int number)
{
return createfunc(number);
}
};
class ModuleManager
{
bool LoadModule(String filename);
IObject * CreateClass(String classname)
{
ClassID class = AvailableClasses.find(classname);
return class.module->CreateObject(class.number);
}
vector<Module*> LoadedModules;
map<String, ClassID> AvailableClasses;
};
模块有一些导出函数来给出它们提供的类的数量和这些类的名称/id,然后存储。所有的类都派生自IObject
,它有一个虚析构函数,存储源模块,并有一些方法来获取类的ID,它实现了什么接口等等。
唯一的问题是每个模块必须手动加载到某个地方(在配置文件中列出,目前)。我想避免显式地这样做(在ModuleManager
之外,在里面,我并不真正关心它是如何实现的)。
我想有一个类似的系统,而不必处理加载模块,只是创建一个对象,(一旦它全部设置)它神奇地出现。
我相信这在某些方面类似于COM打算做的事情。我简单地研究了一下COM系统,但它似乎是令人难以置信的过度杀伤。我只需要系统中已知的类,不需要系统处理的所有其他特性,只需要实现来自某处的接口。
我的另一个想法是使用注册表并保留所有已知/注册类及其源模块和数字的关键,这样我就可以查找它们,并且会出现Manager::CreateClass
发现并神奇地使对象。这似乎是一个可行的解决方案,但我不确定它是否是最佳的,或者我是否在重新发明一些东西。
那么,在所有这些之后,我的问题是:如何处理这个?是否有现有的技术,如果没有,如何最好地设置自己?有没有什么陷阱是我应该注意的?
COM很可能就是你想要的。它是非常广泛的,但你不需要使用所有的功能。例如,您不需要要求参与者注册guid,您可以定义自己的机制来创建接口实例。有许多模板和其他机制可以使创建COM接口变得容易。更重要的是,由于它是一个标准,很容易记录需求。
要记住的一件非常重要的事情是,导入/导出c++对象需要所有参与者使用相同的编译器。如果你认为这对你来说是个问题,那么你应该使用COM。如果你愿意接受这个限制,那么你可以继续做你自己。
我不知道是否有任何技术可以做到这一点。
我确实知道我曾经使用过一个非常类似的系统。我们使用XML文件来描述不同模块提供的各种类。我们等效的ModuleManager将解析xml文件,以根据它们提供的类名和系统配置,在运行时确定为用户创建什么。(请求一个实现接口'I'的对象可以返回任何对象'A', 'B'或'C',这取决于系统的配置方式。)
我们发现的最大问题是系统非常脆弱,有时很难调试/理解。仅仅通读代码,通常几乎不可能看到实例化了哪个具体类。我们还发现维护XML产生了比预期更多的bug和开销。
如果我再次这样做,我将保持通过接口从DLL中公开类的设计模式,但我不会试图构建类的中央注册中心,也不会从IObject等基类派生所有内容。
我会让每个模块负责公开自己的工厂函数来实例化对象。
- g++用户定义的动态链接库上的全局new和delete运算符
- 如何使用C++导出制作动态链接库
- 使用动态链接加载程序 <dlfcn.h> 而不是直接函数调用的目的是什么?
- 动态链接库中C++回调函数
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 如何动态链接 grpc 库 c++?
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- 将函数传递给动态链接库
- aarch64动态链接器rpath使用辅助依赖链接
- 动态链接-Linux与Windows
- 如何将动态链接库与CMake一起使用
- 使用动态链接从.dll库调用函数
- 静态链接 Visual Studio dll 到动态链接的 sfml 项目
- 从另一个动态链接库项目调用静态库函数
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 使用 GCC 的静态和动态链接
- 静态链接MSVC库,动态链接Qt
- 在动态链接中,.exe如何知道在更新库时在哪里搜索库?
- 如何强制Windows.h在Visual Studio中静态链接而不是动态链接?
- 对应于 stdio.h 的库文件是动态链接还是静态链接