[英]I'm getting an access violation when using the LoadLibrary and GetProcAddress in Delphi
I'm getting access violation when trying call a simple dll using LoadLibrary: 尝试使用LoadLibrary调用简单的dll时遇到访问冲突:
Access violation at address 03454D62 in module 'test_dll.dll'. Write of address 00429D24.
Code for Test.DLL: Test.DLL的代码:
library Test_DLL;
uses
dialogs;
{$R *.res}
procedure Test(source, dest : string);stdcall;
begin
messageDlg('Source: ' + source + chr(13) + 'Dest: ' + dest, mtInformation, [mbOk], 0);
end;
Exports
Test;
begin
end.
Calling the function using this: 使用此函数调用:
procedure TForm6.Button1Click(Sender: TObject);
type
TCheckMessage = procedure (test1, test2 : string);
var
CheckMessage : TCheckMessage;
DLLHandle : Cardinal;
const
DLL_FILE = 'test_dll.dll';
DLL_PROC = 'Test';
begin
dllHandle := LoadLibrary(DLL_FILE) ;
if dllHandle <> 0 then
begin
@CheckMessage := GetProcAddress(dllHandle, DLL_PROC) ;
if Assigned (CheckMessage) then
CheckMessage('test1', 'test2') //call the function
else
ShowMessage('"' + DLL_PROC + '" function not found') ;
FreeLibrary(dllHandle) ;
end
else
ShowMessage(DLL_FILE + ' not found / not loaded') ;
end;
This seems like an easy thing to do, but I must be missing something. 这似乎是一件容易的事,但是我必须缺少一些东西。 I did notice that the DLL procedure calls seem to be case-sensitive.
我确实注意到DLL过程调用似乎区分大小写。 It does appear the that procedure call is happening.
似乎过程调用正在发生。 DLLHandle and @CheckMessage are getting populated and the code runs, but throws an access violation as soon as:
DLLHandle和@CheckMessage会被填充并运行代码,但是一旦出现,就会引发访问冲突:
CheckMessage('test1', 'test2')
is called. 叫做。
You are not allowed to pass string
across a DLL boundary. 您不允许跨DLL边界传递
string
。 You might get away with it if you use a shared memory manager (as described in the comment that you deleted from the top of the library unit). 如果您使用共享内存管理器(如从库单元顶部删除的注释中所述),则可能会不满意。 And if you use the exact same version of Delphi to compile both DLL and executable.
而且,如果您使用完全相同的Delphi版本来编译DLL和可执行文件。
Instead you should use interop safe types. 相反,您应该使用互操作安全类型。 For instance
PAnsiChar
, PWideChar
or WideString
. 例如
PAnsiChar
, PWideChar
或WideString
。
Your other problem is a mismatch of signatures. 您的另一个问题是签名不匹配。 The exported function uses
stdcall
calling convention. 导出的函数使用
stdcall
调用约定。 But when you import it, you use the default register
calling convention. 但是,当您导入它时,将使用默认的
register
调用约定。 Clearly the calling convention needs to match. 显然,调用约定需要匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.