我遇到了包含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。感谢
答案 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