var
O: TObject;
Msg: AnsiString; //type depending on DLL
begin
try
CallExternalDll(...);
except
//on E: Exception do might lead to access violations
//because the exception might not be of type Exception
O := ExceptObject;
//Depending on the DLL this or an other cast might
//or might not be necessary:
Msg := PAnsiChar(Exception(O).Message);
raise Exception.Create(Msg);
end;
end;
function ExceptionMatch (Exc : Exception; ExcClass : TClass) : Boolean;
var
CurrClass : TClass;
begin
CurrClass := Exc.ClassType;
while (CurrClass <> nil) do
begin
if SameText (CurrClass.ClassName, ExcClass.ClassName) then
Exit (True);
CurrClass := CurrClass.ClassParent;
end;
Result := False;
end;
5条答案
按热度按时间dgiusagp1#
因为纯DLL的异常是不允许跨越DLL边界的(就像Deltics提到的那样)--不管是什么语言。
你得到了all sorts of trouble there,特别是因为你不知道边界两边是哪种语言、RTL、内存管理器等。
因此,您又回到了经典的错误处理范例:
你可以使用BPL包来代替DLL(如Lars所建议的):在那里,你知道双方将使用相同的RTL和内存管理器。
无论如何,包和BPL通常都会给予您带来版本控制的噩梦(太多的自由度)。
一个更严格的解决方案是使用单片可执行文件;这解决了两个问题:
--杰伦
PS:我把这个作为一个额外的答案,因为这样可以更容易地粘贴链接。
cunj1qz12#
最安全的方法是首先不允许异常从DLL中“逃逸”。
但是如果你无法控制DLL的源代码,因此无法确保这一点,你仍然可以测试异常类名:
xt0899hw3#
如果你为你的应用程序和dll都使用运行时包(至少是rtlxx.bpl),那么两者都有相同的类型,它就能工作。当然这限制了你的dll只能用于 Delphi /BCB。
另一个解决方案是根本不像Deltics建议的那样使用异常。返回错误代码。
或者使用COM。那么你就可以有例外,而不是限制你的dll只限于 Delphi 。
insrf1ej4#
我认为,大家都同意不应该允许从DLL中逃逸异常。
但有时您无法控制DLL,并且无法避免异常问题。
例如,我们遇到了一个外部DLL中的函数问题,该函数被AV软件设置(“勒索软件保护”)阻止,导致 Delphi 中的访问违规。
下面的代码为我们工作:
ukxgm1gy5#
这个解决方案似乎适合我:
我已经准备好让你毁了这个:)
这种做法有什么问题?什么是潜在危险?