我不完全确定如何命名,所以请提前道歉。
你知道,我正在尝试自学Win32 / DirectX编程,使用Delphi(我选择的语言)使用这个网站 - http://rastertek.com/tutindex.html
当然,该网站全部使用C ++,我必须将其移植到Delphi。起初看起来很简单。我正在使用DirectX 11的第二个教程 - 设置框架并显示初始窗口。
现在我的实际问题。我收到了访问冲突错误。所以我发现并开始使用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,但除了主线程之外,它没有列出任何其他内容。 (如果需要这些信息,我很乐意提出来。)
提前感谢所有读过这篇文章的人,我希望能找到一些关于这个问题的帮助,以便我可以继续深造。
答案 0 :(得分: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教程。)
答案 1 :(得分:1)
首先应该尝试摆脱TPersistent继承。如果要将对象传递给库,其接口应与C ++中使用的原始接口完全相同。通过继承TPersistent,您可以在课堂上承担大量的负担,这可能是不需要的,甚至可能是您遇到问题的原因。
此外,如果您发布了例外的确切输出,这将有所帮助。甚至是CallStack。这可能有助于追查错误。