【发布时间】:2015-05-23 19:54:52
【问题描述】:
我正在和其他几个学生一起开发一个游戏,但我遇到了一个问题。
我有一个工厂对象,它有一个名为registeredObjects 的std::vector<BehaviourFactoryCallbackObject>。 BehaviourFactoryCallbackObject 包含用于创建对象的用户给定函数。
此部分位于游戏引擎 (irrlicht) 创建的 .dll 中。
在游戏中,我从这个工厂创建了一个对象,并注册了一些用于创建对象的函数。
然后引擎(.dll)使用这个工厂。
问题是功能似乎没有正确注册,而(根据 Visual Studio 的手表)同时它确实注册了。
我如何初始化工厂和注册函数:
//This part is in the game, not the .dll
factory = new irr::AI::BehaviourFactory();
factory->RegisterBehaviour(ePID_SomeID, SomeBehaviour::GetInstance);
如果我按照这个进入工厂内部,那么新的 BehaviourFactoryCallbackObject 会正确添加到 registeredObjects(根据 Visual Studio 的手表)。但是,一旦我离开该函数,registeredObjects 的大小就会调整回 0。
在某个时刻,大小变为 1,但第 0 个元素包含一个无效地址作为其成员(而不是预期的函数指针)。
factory 曾经是智能指针的一部分。我将其更改为普通指针,希望可以解决此问题。除此之外,我尝试在 google/stackoverflow 上进行搜索,但我不知道要搜索什么。
我的问题:有没有人知道可能是什么问题并知道如何解决它?
工厂必须在游戏引擎中,我的游戏中的代码必须在游戏中。
我用手表试过的东西:
观看factory 并折叠它。
观看factory->RegisteredObjects.size()。
我试图查看 RegisteredObjects 它的地址,但失败了。
如果RegisteredObjects 的地址更改了 4 个或更多字节,我添加了一个断点。没有发生中断(添加元素后除外)。
附加代码:
//.h file, everything in this snippit is in the .dll
typedef IBehaviour* (* GetBehaviourCallBack) (void);
class BehaviourFactoryCallbackObject
{
public:
BehaviourFactoryCallbackObject(int pID, GetBehaviourCallBack pFP) : id(pID), fp(pFP) { }
int GetID();
IBehaviour* BuildBehaviour();
private:
GetBehaviourCallBack fp;
int id;
};
class BehaviourFactory
{
public:
BehaviourFactory(void) { }
void RegisterBehaviour(int pID, GetBehaviourCallBack pFP);
IBehaviour* GetBehaviour(int pID);
private:
std::vector<BehaviourFactoryCallbackObject> registeredObjects;
};
//.cpp file
void BehaviourFactory::RegisterBehaviour(int pID, GetBehaviourCallBack pFP)
{
//This vector does what I expect it to do but only when I am
//inside this function with the debugger
registeredObjects.push_back(BehaviourFactoryCallbackObject(pID,pFP));
}
如果您需要任何其他信息,请说出来。
编辑
一步一步的位置
下面的手表报告都检查相同的向量
我开始游戏,它创建了一个工厂。
我使用RegisterBehaviour(pID, pFP)向这个工厂注册了一个函数
游戏步入函数并在向量中推送BehaviourFactoryCallbackObject
Watch 报告矢量大小为 1
跳出函数,watch 报告向量大小为 0
向工厂注册一个新函数,再次单步执行该函数
立即观看报告大小为 1
新对象被推送,Watch 现在报告大小为 2
再次走出去,watch 报告大小为 0
注册新函数,进入函数
立即观看报告大小为 2
再次推送新对象,watch 报告大小为 3
走出去,再次观看大小为 0 的报告
完成注册,继续..
稍后我们实际使用工厂
此时手表报告大小为 1
第 0 个元素的 fp 的地址无效,id 的地址很大。
调试器因错误的 aloc 异常而中断。
【问题讨论】:
-
离题:通常以小写开头的成员。一些风格指南甚至使用 m_ 作为前缀。
-
我同意。我自己没有写工厂,但它是我调试任务的一部分。我将编辑问题以使其更具可读性。