【发布时间】: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