首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >dll中的过程引发异常后,Delphi FreeLibrary挂起

dll中的过程引发异常后,Delphi FreeLibrary挂起
EN

Stack Overflow用户
提问于 2017-07-25 17:25:49
回答 2查看 2.1K关注 0票数 0

我有一个问题的动态链接库,其中包含过程与火鸟TIBScript。

代码语言:javascript
运行
复制
uses
  System.SysUtils,
  System.Classes,
  DLLMainData in 'DLLMainData.pas' {DataModule2: TDataModule};

{$R *.res}

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

exports
  RunScript;

begin
end.

dll过程

代码语言:javascript
运行
复制
class function TDataModule2.RunScriptProc: boolean;
begin
  with self.Create(nil) do
  begin
    try
      IBDatabase1.Open;
      IBScript1.ExecuteScript;
    finally
      IBDatabase1.Close;
      Free;
    end;
  end;
end;

现在我从exe中调用这个过程,如下所示:

代码语言:javascript
运行
复制
procedure TForm2.Button1Click(Sender: TObject); 
var
  Handle: Integer;    
  LibraryProc :procedure();stdcall;
begin
   Handle := LoadLibrary('dllka.dll');
   if Handle <> 0 then
   begin
     try
       LibraryProc := GetProcAddress(Handle,'RunScript');
       if @LibraryProc = nil then
         raise Exception.Create('erorr')
       else
         LibraryProc();
     finally
       Showmessage('Before free library');
       FreeLibrary(Handle);
       Handle := 0;
       LibraryProc := nil
     end
   end;
   Showmessage('ok');
end;

当TIBScript在执行时引发异常( sql出现问题等)在主应用程序中(此过程从其调用)挂起在FreeLibrary()上。当脚本执行时没有问题时,一切都很正常。我创建了一个小示例,因为我认为问题是将参数传递给库,但事实并非如此。

感谢您的帮助。我使用的是Delphi XE2。谢谢

EN

回答 2

Stack Overflow用户

发布于 2017-07-25 18:10:48

根据约定,DLL不会从导出的函数中引发异常。您的DLL违反了此合同。

通过处理任何导出函数中的所有异常来修复此问题。例如,将这些异常转换为错误代码返回值。这是不加区别地使用捕获所有异常处理程序的少数几次中的一次。

导出的函数将如下所示:

代码语言:javascript
运行
复制
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;
票数 4
EN

Stack Overflow用户

发布于 2020-03-21 06:10:53

@David Heffemen是正确的。您不能从动态链接库抛出异常,但如果您打算在Delphi捕获异常时退出动态链接库,则可以使用ExitCode退出。

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

代码语言:javascript
运行
复制
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#中的异常消息是:

代码语言:javascript
运行
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45299131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档