2011-03-07 53 views
4

我不完全确定如何命名这个,所以提前道歉。德尔福Win32编程/访问冲突问题

你看,我想教自己的Win32/DirectX的编程,使用本网站利用德尔福(我选择的语言) - http://rastertek.com/tutindex.html

当然,该网站是所有在C++中,我有口它到德尔福。起初,这似乎很简单。我正在开发DirectX 11的第二个教程 - 设置框架并获得初始窗口。

现在我的实际问题。我遇到了Access Violation错误。所以我发现并开始使用MadExcept来试图找出发生了什么。所以它告诉我线条,但我对如何解决手头的问题毫无头绪。

我有一切设置为模仿以及我可以原始的源代码。唯一真正的区别是,在一个指向变量类的指针的情况下,例如m_input,m_grahics和system,我为这些指定了一个类型。所以我有TSystemClass,TInputClass,TGraphicsClass,然后我有PSystemClass等=^TSystemClass等。我认为这会让事情变得更简单和更整洁。在一个侧面说明中,我假设它应该说,但我为复制构造函数的构造使最初的类继承自TPersistent,所以我可以使用它的Assign过程。

因此,回到访问冲突错误。首先,问题出现在主程序中,系统是PSystemClass类型的。因此,出于我未知的原因,当我尝试使用system.create时,它正是在这个瞬间创建访问冲突。然后我意识到,我没有将系统分配给system.create。所以我尝试了这一点,它说,并且我认为在编译时两个不兼容的错误,因为system.create是TSystemClass类型,而系统是PSystemClass。所以我尝试了类型化,并且工作。但再一次,仍然遇到可怕的访问违规。

那么我有一个奇怪的想法,也许我应该从TSystemClass本身调用正则构造函数。我试过了,需要再次调整。所以我做了。它的工作!不再有访问违规错误!现在...新问题!或者在这种情况下是“问题”。 MadExcept中的调用堆栈中列出了3件事情。第一个:

m_hinstance := GetModuleHandle(nil); 

这是说,这是造成访问冲突错误。虽然这是为什么呢?根据我的理解和阅读,如果GetModuleHandle设置为null/nil,它应该检索调用它的文件的句柄,对吧?根据文档所述,这应该是可执行的。

但是,我不确定是否我有主程序,系统类的东西,输入类的东西,和图形类的东西,所有在不同的程序/单元文件模仿原始源的性质码。那么这可能是什么原因造成的?如果是的话,我会如何解决它?通过将单元文件中的所有代码放入主程序文件中?尽管如此,以我个人的观点来看,这将是相当混乱和不直观的。

下一个让我更加困惑。

InitializeWindows(ScreenWidth, ScreenHeight); 

我没有处理任何其他的功能,以注册窗口类和设置窗口和所有在这里。所以我不太确定这里的问题是什么,因为它只处理2个参数,而且它们已被定义,并且在调用之前已经完成。所以我不太确定这里的问题究竟是什么以及究竟是什么导致了访问冲突。

,最后的最后一个是在主程序:

return := system.initialize; 

回报是什么,我在原始源代码的结果变量的所有实例使用,结果当然是一个内置变量的所有功能。

我想如果系统永远无法正确地做到它的意义,那么可能会/应该发生在这里。同样,因为我之前使用TSystemClass.Create(类型化为PSystemClass)来创建系统会在这里执行任何操作吗?它可能与其他两个链接,因为他们不能正确地做自己的事情?

然后在最后的笔记;在MadExcept的调用堆栈中实际上还有一件事情。

它说在模块部分Kernel32.dll,但除了主线程,它没有列出其他任何东西。 (如果需要这些信息,我会很乐意把它提出来)。

预先感谢任何人阅读了这么多,我希望能找到一些关于这个问题的帮助,以便我可以进一步学习。

+1

这太叙述了。你得到的几个代码示例嵌入了长段文本。发表一些代码更短,更容易阅读,并且不太容易出错,然后说明你使用类型转换。 –

+2

并给出一些提示:当你声明TSomething类型的变量(其中TSomething是一个类)时,它已经是一个指针了:在移植C++代码时考虑到这一点。当你说'^ TSomething'时,就像在C++中使用'TSomething **'(双指针)。如果你把'TSomething'强加给'^ TSomething',你当然会遇到麻烦。用C++术语来说,你刚刚将'TSomething *'转换成'TSomething **'。并且访问冲突“弹出”的位置并不总是指示错误的原因。尝试使用FASTMM4和Full Debug来诊断AV和内存损坏。 –

+1

我们不会通过电子邮件发送给您。如果你展示了一些代码,我们可以帮助你。 –

回答

4

你正在实例化你的类都是错误的。下面是TSystemClass.Initialize一个例子:

m_Input := PInputClass(m_Input.create); 

这就是你声明为PInputClass的变量。

此前,在TSystemClass.Create,你初始化变量:

m_Input := nil; 

所以,既然你有一个空引用,应该明确的是,你不能调用它的任何方法。尤其是,你不能打电话给Create。相反,请致电Create对您要实例化的TInputClass.Create

该构造函数返回您构造的类型的值,TInputClass。它不会返回PInputClass,所以你的类型转换是错误的。正如Cosmin的评论所解释的,Delphi对象变量是指针已经是。必须声明基于Delphi类的指针类型非常罕见。正确的代码是这样的:

m_Input := TInputClass.Create; 

该行后,检查是否m_Input为空。在Delphi中你永远不需要这么做;一个构造函数要么返回一个有效的对象,要么根本不返回。如果在构造对象时出现问题,构造函数将引发异常,并且赋值语句从不执行。 (最初的C++代码也是错误的,new运算符在失败十几年后还没有返回空指针,远远没有人开始编写DirectX 11教程。)

+0

我错过了一些明显的东西吗?你提到的代码在哪里? –

+0

我明白了,那很有洞察力!谢谢万亿!所以,现在我相信我所有的类都正确地实例化了。尽管现在我仍然在MadExcept的调用堆栈中收到了有关TSystemClass的构造函数的内容。不管顺序继承后的第一个代码位;始终是罪魁祸首。如果我把m_input和m_graphics的零分配分配给它,那么它似乎会抱怨结束;的构造函数。 –

+0

@David,Asurai在对Fmotis的回答发表评论时给了MediaFire链接。 –

1

您应该首先尝试摆脱TPersistent继承。如果你想将一个对象传递给一个库,它的接口应该与C++中使用的原始接口完全相同。通过从TPersistent继承,您可以将大量负载加入到您的课堂中,这可能不是您需要的,或者甚至可能是您遇到问题的原因。

此外,如果您发布例外的确切输出,这将有所帮助。甚至是CallStack。这可能有助于找出错误。

+0

超级长叙述的道歉,每个人。不过,我觉得我需要解释所有事情,并且觉得只需发布300多行代码或其他内容对任何人都有帮助。尽管我再次为非常小的代码片断道歉。这是我整个项目的媒体消息链接。 http://www.mediafire.com/?82w27c08d4fk6tg我已经拿出了指针类,以及复制构造函数。我不知道他们是否会实施,但如果他们是我会处理它。谢谢大家到目前为止的建议! –