首页 > delphi > 如何动态正确调用DLL

如何动态正确调用DLL (How to properly call a DLL dynamically)

2018-12-18 delphi

问题

我试图按照这个教程链接,但它始终抛出访问违规错误,因为FreeLibary。我哪里做错了?这是我的DLL代码:

library EditDocument;

uses
  System.SysUtils,
  Vcl.Dialogs,
  System.Classes,
  dxmdaset;

{$R *.res}



procedure EditDocument2(const fieldName : string); stdcall;
begin
  ShowMessage(fieldName);
end;


exports EditDocument2;

begin
end.

这就是我在主程序中调用它的方式:

procedure TfrmMain.btn1Click(Sender: TObject);
type
  TDLL_EditDocument = procedure (const fieldName : string); stdcall;

var
  dllHandle : THandle;
  aFunction : TDLL_EditDocument;
begin

  dllHandle := LoadLibrary('EditDocument.dll') ;

  if dllHandle = 0 then
  begin
    CommonHelper.MsgDlgError('DLL not found EditDocument.dll');
    Exit;
  end;

  @aFunction := GetProcAddress(dllHandle, 'EditDocument2') ;
  if Assigned (aFunction) then
  begin
    aFunction('test');
  end;

  FreeLibrary(dllHandle);


end;

另外,我在我的主项目中使用了Sharemem,它是uses子句中的第一个单元。我已经尝试将stdcall更改为cdecl,将参数设置为shortstring,甚至删除所有参数,但它在FreeLibrary期间始终抛出错误。我确信这是一个简单的,但它已经花了我2个小时。我正在使用Delphi XE7。提前致谢

解决方法

如果你想使用,Sharemem你也需要在DLL项目中使用它。你的DLL项目的use子句中缺少它。

除了该错误之外,最可能出现错误的是您使用的其中一个单元的终结代码。假设已知RTL和VCL单元处理动态加载和卸载,则指向该指针dxmdaset。尝试从DLL中删除该单元。

最后,有时外部DLL会引发在调试器中触发的第一次机会异常,但实际上不会导致任何问题。您是否100%确定呼叫FreeLibrary实际上并未成功返回。您可以通过捕获并输出返回值来完成此操作FreeLibrary

问题

I tried to follow this tutorial link but its always throwing access violation error druing FreeLibary. Where did I go wrong? Here is my DLL code :

library EditDocument;

uses
  System.SysUtils,
  Vcl.Dialogs,
  System.Classes,
  dxmdaset;

{$R *.res}



procedure EditDocument2(const fieldName : string); stdcall;
begin
  ShowMessage(fieldName);
end;


exports EditDocument2;

begin
end.

and this is how I called it in my main program :

procedure TfrmMain.btn1Click(Sender: TObject);
type
  TDLL_EditDocument = procedure (const fieldName : string); stdcall;

var
  dllHandle : THandle;
  aFunction : TDLL_EditDocument;
begin

  dllHandle := LoadLibrary('EditDocument.dll') ;

  if dllHandle = 0 then
  begin
    CommonHelper.MsgDlgError('DLL not found EditDocument.dll');
    Exit;
  end;

  @aFunction := GetProcAddress(dllHandle, 'EditDocument2') ;
  if Assigned (aFunction) then
  begin
    aFunction('test');
  end;

  FreeLibrary(dllHandle);


end;

Also, I have use Sharemem in my main project, its the first unit in the uses clause. I have tried changing stdcall to cdecl, making parameters to shortstring, and even removing all parameters but its always throwing error during FreeLibrary. I'm sure this is an easy one but it already cost me 2 hours. I'm using Delphi XE7. Thanks in advance

解决方法

If you want to use Sharemem you need to use it in the DLL project also. It is missing from your DLL project's use clause.

Beyond that error, the most likely suspect for your error is the finalization code of one of the units that you use. Given that the RTL and VCL units are known to handle dynamic loading and unloading, that points the finger at dxmdaset. Try removing that unit from your DLL.

Finally, sometimes external DLLs will raise first chance exceptions that trigger in the debugger, but do not actually cause any problem. Have you made 100% sure that the call to FreeLibrary does not in fact return successfully. You can do this by capturing and outputting the return value of FreeLibrary.

相似信息