我尝试按照本教程link进行操作,但是由于 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。 预先感谢
答案 0 :(得分:2)
如果要使用Sharemem
,则还需要在DLL项目中使用它。 DLL项目的use子句中缺少它。
除该错误外,最有可能引起您的错误的怀疑是您使用的单元之一的完成代码。已知RTL和VCL单元可以处理动态加载和卸载,这将手指指向dxmdaset
。尝试从DLL中删除该单元。
最后,有时外部DLL会引发在调试器中触发的首次机会异常,但实际上不会引起任何问题。您是否已100%确定对FreeLibrary
的呼叫实际上并未成功返回。您可以通过捕获并输出FreeLibrary
的返回值来做到这一点。
答案 1 :(得分:1)
使用Sharemem
时,它必须是主项目和库中的第一个单元。
当删除所有不应该成为问题的参数时(另请参见Sharemem, when is it not needed),但是尝试时可能没有编译两个项目。当您仅点击编译/运行,甚至编译时,只会编译当前项目。玩转过程签名时,请确保运行Project-> Build All。