简体   繁体   English

在Delphi中使用LoadLibrary和GetProcAddress时遇到访问冲突

[英]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 . 例如PAnsiCharPWideCharWideString

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM