Delphi FreeLibrary在dll raise exeception的过程后挂起

时间:2017-07-25 09:25:49

标签: delphi delphi-xe2

我遇到了包含Firebird TIBScript程序的dll问题。

<div class="wpr">
  <div class="wpr-item">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
  <ol class="carousel-indicators">
    <li class="active"></li>
    <li></li>
    <li></li>
  </ol>
</div>

dll程序

uses
  System.SysUtils,
  System.Classes,
  DLLMainData in 'DLLMainData.pas' {DataModule2: TDataModule};

{$R *.res}

Procedure RunScript();stdcall;
begin
   TDataModule2.RunScriptProc;
end;

exports
  RunScript;

begin
end.

现在我从exe中调用此过程如下:

class function TDataModule2.RunScriptProc: boolean;
begin
  with self.Create(nil) do
  begin
    try
      IBDatabase1.Open;
      IBScript1.ExecuteScript;
    finally
      IBDatabase1.Close;
      Free;
    end;
  end;
end;

当TIBScript在主应用程序中执行(sql等问题)时引发异常(这个程序正在调用)挂起在FreeLibrary()上。当脚本执行没有问题时,一切正常。我创建一个小例子,因为我认为问题在于将params传递给库,但事实并非如此。

感谢任何帮助。我正在使用Delphi XE2。感谢

2 个答案:

答案 0 :(得分:2)

合同中的DLL不会从导出的函数中抛出异常。你的DLL破坏了这份合同。

通过处理任何导出函数中的所有异常来解决问题。例如,将这些异常转换为错误代码返回值。这是使用不加区分的catch-all异常处理程序的合理次数之一。

您导出的功能如下所示:

function RunScript: Integer; stdcall;
begin
  Try
    TDataModule2.RunScriptProc;
    Result := ERROR_CODE_SUCCESS;
  Except
    Result := ...; // your code to convert exception to error code goes here
  End;
end;

答案 1 :(得分:0)

@David Heffemen是正确的。您不能从DLL引发异常,但是如果您打算在Delphi捕获异常时退出DLL,则可以使用ExitCode退出。

我继承了在无法加载DLL时引发异常的代码,但是在找不到DLL时只是挂起了代码。我解决了这个问题,检查文件是否存在并分配了句柄,将ExitCode设置为1,然后退出。当我调用导出的函数时,它在C#中产生了一个很好的异常:

procedure LoadMyDll();
  begin
    if (FileExists(MY_DLL_NAME)) then
      _hMy32Dll := LoadLibrary(PChar(MY_DLL_NAME));
    if (_hMy32Dll = 0) then
      begin
        System.ExitCode:=1;
        exit;
      end;
  end;

C#中的异常消息为:

System.DllNotFoundException: Unable to load DLL 'C:\src\MyDLL\Delphi\Win32\Debug\MyDLL.dll': A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)
   at MyDLLTest.Program.Min(Int32 x, Int32 y)
   at MyDLLTest.Program.Main(String[] args) in C:\src\MyDLL\CSharp\MyDLLTest\MyDLLTest\Program.cs:line 23