我在 Delphi 2010 中构建了一个 dll,它在我的 delphi 7 应用程序中使用。
我知道 unicode AnsiString / string 问题,根据我的测试,一切正常,直到我的 delphi 2010 dll 没有引发异常。
事实是,是否有任何与 unicode/AnsiString 世界兼容的特殊/处理异常?也就是说,我的 Delphi 2010 是否能够引发可以在我的 delphi 7 应用程序中适当处理的异常?
感谢任何帮助。
达尼洛。
我在 Delphi 2010 中构建了一个 dll,它在我的 delphi 7 应用程序中使用。
我知道 unicode AnsiString / string 问题,根据我的测试,一切正常,直到我的 delphi 2010 dll 没有引发异常。
事实是,是否有任何与 unicode/AnsiString 世界兼容的特殊/处理异常?也就是说,我的 Delphi 2010 是否能够引发可以在我的 delphi 7 应用程序中适当处理的异常?
感谢任何帮助。
达尼洛。
看到梅森和杰罗恩都提示我,这里是:(杰罗恩,不要放弃你的,你也有有效的积分)。
Jeroen 指出,任何特定语言都不应跨越 dll 边界。在某种程度上我同意。这取决于 dll 的预期用途,尤其是涉及到诸如字符串之类的语言特定功能时。如果您开发的 dll 将专门用于 Delphi 项目,尤其是当它仅用于您自己的 Delphi 项目时,没有理由为了避免字符串越界而弄乱 PChar 之类的东西。
因此,即使异常是特定于语言的,对我来说,这并不是不允许异常转义 dll 的主要原因。事实上,由于它们的语言特殊性,不可能在 dll 之外处理它们。
不允许异常逃逸 dll 的基本原因与不允许异常逃逸线程的基本原因相同:清理自己的烂摊子。另外:转义线程的异常会导致您的应用程序崩溃。对于转义 dll 的异常而言,情况可能并非如此,但 dll - 甚至不仅仅是一个线程应该是一个自包含的实体,与调用它的人无关,这包括在处理不可预见的情况时独立于调用者,即例外。
那么如何确保 dll 不会践踏调用方?我想有很多条通往罗马的道路,但我认为最简单的是 OLE 所做的:
每个导出的方法都应该返回一个代码,告诉调用者是否一切正常,或者是否出现问题。
在返回代码中要具体。不要只报告出了什么问题,要有一个代码来阻止该方法执行它被调用的所有操作。因此有 DLL_OK、DLL_OUT_OF_MEMORY、DLL_FILE_NOT_FOUND、DLL_INVALID_XXX(用于报告无效输入参数)等代码。
在调用 dll 的应用程序中,编写一个通用的 DLL_Check 函数来检查返回码并引发适当的异常,以便其余代码可以根据需要处理这些异常。
使用特定的异常类来执行此操作。即一个通用的 EDllError 异常类及其各种后代,用于您需要处理的特定情况。这极大地帮助了除 E... 进行编码。
因为方法的返回值用于ok/error报告:在需要返回有意义值的方法中使用out或var参数。
查看有关 OLE 拖放的 msdn 文档以获取特定返回代码的示例以及如何使用 var 和 out 参数与调用者交换信息。
链接:
数据传输入口点: http: //msdn.microsoft.com/en-us/library/ms680067 (v=VS.85).aspx
DoDragDrop 函数: http: //msdn.microsoft.com/en-us/library/ms678486 (v=VS.85).aspx
我会回答的;如果 Marjan 发帖,我会放弃我的。
编辑:Marjan 要求我保留我的答案;如果你喜欢我的,请奖励她的回答(因为我的回答受到了她的第一条评论的极大启发)。
关于 DLL 的整个想法是它们与语言无关。
异常是高度依赖于语言的特性(许多语言都有它们,但每种语言都以不同的方式实现它们,有时——在本例中为 Delphi——相同语言的不同版本使用不同的方式)。
所以 DLL 应该只让与语言无关的特性跨越 DLL 边界。
与语言相关的功能不应跨越 DLL 边界。
这包括例外。
这意味着您应该寻找替代方案。
Windows API 为此使用错误代码、GetLastError和FormatMessage。
你可以在你的 DLL 中设计类似的东西。
请注意,尽管 Delphi 字符串也依赖于语言,因此您应该基于字符数组(或指向字符数组的指针)实现类似 FormatMessage 的东西。
——杰伦
Delphi 总是“容忍”在调用者和被调用者之间跨越常规 DLL 边界传播的异常。然而,只有当且仅当调用者和被调用者都具有相同的 Delphi 版本时,这种“容忍度”才存在。它在版本之间起作用的事实仅仅是因为对于几个版本,Exception 类的布局和声明没有改变。引入 Delphi 2009 时,许多低级实现细节发生了变化(最明显的是字符串的内部实现)。这就是明显“失败”的原因。异常不应逃脱 dll 的一条评论非常恰当。