【问题标题】:try/finally results in exception尝试/最终导致异常
【发布时间】:2023-03-22 13:26:02
【问题描述】:

调用外部 C/C++ 库的方法,该库返回指向 Delphi XE6 应用程序的指针。然后有一个 try/finally 块,并在 finally 中释放 C/C++ 库分配的内存。如果我在最后释放内存,我会在空闲时获得特权指令异常。如果我在 try/finally 块之外释放内存,也不例外。

// This crashes
ptr := CMethod();

try
  // 
finally
  freeCPtr (ptr);
end

// This doesn't crash
ptr := CMethod();
freeCPtr (ptr)

请注意,freeCPtr() 是 C 库导出的方法,旨在释放 CMethod() 返回的指针。两个独立的第三方开发人员已证明 CMethod() 和 freeCPtr() 在 C 应用程序中可以正常工作。我很想知道为什么使用 try/finally 可能会导致异常?

更新 原来 C/C++ 库的作者已将他们的调用约定从 stdcall 更改为 cdecl。通常,当出现问题时,我会首先检查调用约定,但我知道我以前的代码运行良好,因此最初并没有考虑检查调用约定。故事的寓意是,每当调用外部库时出现奇怪的行为时,检查:1)调用约定是兼容的; 2)您将正确的类型传递给外部库。

【问题讨论】:

  • 我应该澄清一下,freeptr() 函数是由 C 库导出的。我会更新问题以反映这一点。
  • 啊,好吧,这样更好。我认为这是德尔福方面的一个功能;-)。
  • freeCPtr会不会从C端抛出异常?
  • 我唯一能想到的是,在C 方面,在某些情况下会出现释放和分配问题(一些细微的错误?)。例如使用 C++ new 运算符分配内存并使用 free 而不是 delete 释放它
  • 在 Delphi 方面,我使用与以前相同的调用约定,stdcall。我刚刚在 XE 上尝试过,但它也失败了,这对我来说是个新闻。因此,我认为 C/C++ 方面发生了一些变化,可能是调用约定的变化。在这个阶段,我不认为这是我想知道的德尔福错误。我会进一步调查。

标签: delphi


【解决方案1】:

很难看出问题出在哪里,但根据我的经验,像这样无法解释的问题在一个版本中有效,在另一个版本中有效,尤其是在调用外部 C/C++ .dll:s 时,当优化设置为开启时出现。

确保在您正在使用的项目设置或配置文件中未将优化设置为开启,看看是否有任何不同。当然,在单元本身中使用 {$Optimization Off} 也可以。

我意识到这可能更像是一个评论而不是一个答案,但我是如此的新手,所以我没有那么多积分。 :-)

【讨论】:

  • 我试过了,简短的回答是否定的。相反,我决定接受一些其他的建议,这些建议是我拍摄新闻并编写一个小的 c/c++ dll 来测试问题。这工作得很好。然后我开始怀疑原始代码的作者是否改变了一些东西。事实证明,之前的开发人员在没有告诉任何人的情况下更改了调用约定。最后,我通过将 stdcal 更改为 cdecl 解决了问题!
  • 哦,这很烦人。嗯,很高兴听到它成功了。如果您愿意,您可以使用“解决方案”或答案来更新您的问题,这样其他人就不必阅读所有这些 cmets 来获得答案。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
相关资源
最近更新 更多