需构建跨模块反射机制:一、定义纯虚IPlugin接口与C风格工厂函数;二、主程序用映射表注册DLL类型;三、模板工厂函数校验并创建对象;四、通过destroy_instance隔离内存管理;五、各DLL提供类型枚举接口供动态查询。

如果您希望在C++项目中实现运行时动态加载功能模块并支持类型信息查询与对象创建,则需构建一个不依赖编译期绑定的反射机制。以下是实现该架构的关键步骤:
一、定义跨模块稳定的抽象接口
为确保DLL与主程序间二进制兼容,必须使用纯虚基类作为契约,所有导出类型均继承自统一接口,并禁用异常与RTTI以外的运行时依赖。接口需以C风格函数导出,避免C++名称修饰问题。
1、声明IPlugin接口,仅含virtual destructor与纯虚函数get_type_name()、create_instance();
2、在头文件中使用extern "C"声明工厂函数create_plugin(),返回IPlugin*;
3、将接口头文件置于独立公共目录,主程序与各DLL均包含该头文件且不引入STL或智能指针;
4、在DLL源文件中实现IPlugin派生类,并提供extern "C" __declspec(dllexport) create_plugin()函数;
二、实现基于字符串类型的插件注册中心
主程序需维护一张全局映射表,将类型名称字符串关联至对应DLL句柄及工厂函数指针,避免硬编码类型分支,支持任意新增插件无需重新编译主程序。
1、定义std::unordered_map<:string std::pair create_plugin_func>>类型注册表;
2、封装load_plugin(const char* dll_path)函数,调用LoadLibraryA获取HMODULE,再通过GetProcAddress获取create_plugin地址;
3、从DLL中调用一次create_plugin()获取IPlugin实例,调用其get_type_name()获取键名,插入注册表;
4、提供find_plugin(const char* type_name)接口,返回对应工厂函数指针,供后续实例化调用;
三、构建类型安全的对象创建工厂
工厂需屏蔽底层DLL加载细节,对外暴露统一的模板化create
1、声明template
2、在函数体内调用find_plugin(T::static_type_name())获取工厂函数指针;
3、执行工厂函数获得IPlugin*,执行dynamic_cast
4、若转型失败,返回nullptr并记录类型不匹配错误;
四、实现DLL生命周期与资源隔离管理
每个DLL应独立管理自身内存分配与释放,主程序不得delete由DLL创建的对象,必须通过插件提供的destroy_instance()接口回收资源,防止堆不一致崩溃。
1、在IPlugin接口中增加virtual void destroy_instance(IPlugin* obj) = 0;
2、各DLL实现该函数,内部调用delete static_cast
3、主程序在销毁对象时,先查注册表获取对应DLL的destroy_instance函数指针;
4、调用该函数完成析构,而非直接使用delete操作符;
五、支持运行时类型信息查询与枚举
反射系统需提供获取已加载插件类型列表的能力,便于UI动态生成配置项或调试器展示可用组件,所有信息必须来自DLL自身提供,主程序不维护硬编码列表。
1、扩展IPlugin接口,增加static std::vector<:string> get_all_known_types()纯虚函数;
2、各DLL实现该函数,返回本DLL内所有可创建类型的名称集合;
3、主程序遍历注册表,对每个已加载DLL调用其get_all_known_types();
4、合并所有返回结果至全局std::set<:string>,去重后供外部查询;
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











