我目前正致力于一个实现基于框架的架构的游戏引擎。
通过使用.so库将这些框架动态加载到引擎中。
为了说明框架的用法,这里有一个小图: Engine/Frameworks interactions
(请注意,引擎也知道FrameworkTpl和SpecificFrameworkTpl类型)
正如我们所看到的, specificFrameworkImplementation 类被编译为共享库(.so)并继承自 specificFrameworkTpl ,它本身继承自 FrameworkTpl
编译完成后,库将在运行时加载到引擎中,框架的实例将作为 FrameworkTpl 进行检索。
此时如果我调用 FrameworkTpl 方法,它将像魅力一样工作(很明显是的......)。
永远不会,如果我尝试在dynamic_cast
的帮助下将此实例向下转换为 specificFrameworkTpl ,它将返回nullptr
。
通过我的研究(在阅读勒芒页面和StackOverflow答案的过程中持续了大约一周),我看到人们正在讨论要提供给dlopen
功能的标志,例如 RTLD_NOW 或删除 RTLD_LOCAL 以支持 RTLD_GLOBAL ,但它们都不适合我,g ++标志(-rdynamic
)也是如此。
代码:
以下为GuiFrameworkTpl
specificFrameworkTpl
的示例
和FrameworkUI
specificFrameworkImplementation
。
FrameworkTpl
class FrameworkTpl
{
protected:
std::string _name;
public:
FrameworkTpl(const std::string &name):
_name(name)
{
}
virtual ~FrameworkTpl(void)
{
}
public:
virtual std::string getName(void) const
{
return (this->_name);
}
};
GuiFrameworkTpl
class GuiFrameworkTpl : public FrameworkTpl
{
public:
GuiFrameworkTpl(const std::string & name) :
FrameworkTpl(name)
{
}
virtual ~GuiFrameworkTpl(void)
{
}
virtual void displaySquare(int x, int y, int size) = 0;
};
FrameworkUI
class FrameworkUI : public GuiFrameworkTpl
{
public:
FrameworkUI();
~FrameworkUI();
public:
void displaySquare(int x, int y, int size);
};
extern "C"
{
FrameworkUI* CObject()
{
return (new FrameworkUI);
}
void DObject(FrameworkUI* obj)
{
delete obj;
}
}
使用该库并从中投射内容的应用程序: (此处,以前类中的Xxx用作" Gui")
GuiFrameworkTpl* GUISystem::cast_f(const std::shared_ptr<FrameworkTpl>& src)
{
auto ptr = src.get();
Log::print(ptr);
if (!ptr) return nullptr;
Log::inform(ptr->getName());
auto dst = dynamic_cast<GuiFrameworkTpl*>(ptr);
Log::print(dst);
return dst;
}
我应该拥有什么:
当我加载我的库并调用CObject()
时,它应该创建一个 FrameworkUI 的实例,我在 FrameworkTpl 中获得,然后我只需要dynamic_cast它作为 GuiFrameworkTpl 以访问特定方法。
我真正拥有的东西:
当我加载我的库并调用CObject()
时,它会创建一个 FrameworkUI 的实例,我将其存储在 FrameworkTpl 中(顺便说一句,我可以调用{{ 1}}方法成功,因此实例有效)。但是当我尝试将其转换为 GuiFrameworkTpl 时,它会给我一个getName()
。
最后一个功能打印出来:
nullptr
如果有人对如何解决这个问题有一些线索,我将非常感激, 提前致谢