我在dll中创建了一个打开表单然后打印报表的过程.这个过程完全适用于exe.我已经包含了包含此过程的单元并在dll中形成并导出过程如下:
{$R *.res}
Procedure PrintTopSellers; stdcall;
begin
Form1 := TForm1.create(nil);
GetMonth := TGetMonth.create(nil);
Form1.PrintTopSellers;
end;
exports PrintTopSellers;
begin
end.
Run Code Online (Sandbox Code Playgroud)
现在我从exe调用此过程PrintTopSellers,如下所示:
procedure TForm1.Button5Click(Sender: TObject);
type
TRead_iButton = function :integer;
var
DLL_Handle: THandle;
Read_iButton: TRead_iButton;
Begin
DLL_Handle := LoadLibrary('c:\Catalog.dll');
if DLL_Handle <> 0 then
begin
@Read_iButton:= GetProcAddress(DLL_Handle, 'PrintTopSellers');
Read_iButton;
end;
application.ProcessMessages;
FreeLibrary(DLL_Handle);
end;
Run Code Online (Sandbox Code Playgroud)
对程序的调用完美无缺.但是,在我关闭调用exe之后,我收到了访问冲突 - "地址00BAC89C处的访问冲突.读取地址00BAC89C".
感谢任何帮助.我正在使用Delphi 7.谢谢
您正在Form1DLL 中创建一个窗口控件.但你永远不会破坏它.然后卸载DLL,卸载实现DLL创建的所有窗口的窗口过程的代码.大概是当进程关闭时,会调用窗口过程,但不再有代码了.
通过销毁DLL创建的所有对象来解决此问题.在我看来,最好的方法是在PrintTopSellers终止时这样做.
Procedure PrintTopSellers; stdcall;
begin
Form1 := TForm1.create(nil);
try
GetMonth := TGetMonth.create(nil);
try
Form1.PrintTopSellers;
finally
GetMonth.Free;
end;
finally
Form1.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
在加载DLL的代码中,TRead_iButton声明不正确.它应该是
TRead_iButton = procedure; stdcall;
Run Code Online (Sandbox Code Playgroud)
但这实际上并没有解释这里的问题,因为签名不匹配对于无参数过程是良性的.