我正和其他几个学生一起玩游戏,我刚遇到一个问题。
我有一个工厂对象,其中std::vector<BehaviourFactoryCallbackObject>
名为registeredObjects
。 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
退出功能,观察报告矢量大小为0
向工厂注册新功能,再次插入功能
现在观看报告的大小为1
推送新对象,Watch现在报告大小为2
再次退出,观看大小为0的报告
注册新功能,进入功能
现在观看报告的大小为2
再次按下新对象,观看报告大小为3
走出去再次观看大小为0的报告
完成注册,继续..
片刻之后我们实际上使用了工厂
此时,手表报告的大小为1
第0个元素的fp
地址无效,id
的地址为负数
调试器因aloc异常错误而中断。
答案 0 :(得分:1)
您的问题没有提供足够的信息,这使得撰写准确答案变得更加困难。说这个,我会说出我的想法:
我怀疑在线:
registeredObjects.push_back(BehaviourFactoryCallbackObject(pID,pFP));
我总是怀疑temporary objects。
尝试:
BehaviourFactoryCallbackObject BFC(pID,pFP);
registeredObjects.push_back(BFC);
我在另一个帖子中读到VS2012 might have a bug on move semantics。
您还可以进行以下测试:
为BehaviourFactoryCallbackObject
实现析构函数并在其中设置断点,并监视被调用的析构函数。如果析构函数被调用,那么当执行流程离开函数作用域时,临时对象正在销毁。
答案 1 :(得分:0)
最终解决了它。 包含工厂的对象被删除,稍后使用如下:
if (delete)
delete object;
//Some code..
return new fooObject(.., .., object->factory, ..);
所以我很蠢。
情况仍然很奇怪,我通过使用不同的编译器(在这种情况下甚至是不同的IDE,xcode)找到了这个问题。这款调试手表没有漏洞,更容易找到问题。