gpt4 book ai didi

windows - 如何在 Delphi 的多线程中加载一个 DLL?

转载 作者:可可西里 更新时间:2023-11-01 10:54:40 30 4
gpt4 key购买 nike

也许我错过了什么,我不知道这里发生了什么。

我正在尝试在 TThread 对象的多个实例中加载同一个 DLL。

这是我的 DLL 代码:

library MyCalcFor32;

uses
SysUtils,
Classes,
uRunner in 'uRunner.pas';

Exports EVal;

{$R *.res}

begin
end.

这是 uRunner.pas:

unit uRunner;

interface

uses SysUtils,
Classes;

function EVal(Valor: WideString): WideString; stdcall; export;

implementation

function EVal(Value: WideString): WideString; stdcall; export;
begin
Result := Value+' xxx';
end;

initialization

finalization

end.

这是加载 DLL 的程序:

procedure TfrmMain.FormCreate(Sender: TObject);
var I: Integer;
begin
SetLength(Threads, 10);
for I:= 0 to 9 do
begin
Threads[I] := TWorker.Create(Self.Handle, I+1, Memo1.Text, ExtractFilePath(ParamStr(0)));
end;
end;


procedure TfrmMain.btnExecuteThreadsClick(Sender: TObject);
var I: Integer;
begin
ClearMemos([MT1, MT2, MT3, MT4, MT5, MT6, MT7, MT8, MT9, MT10]);

for I:= 0 to 0 do //to 9, for multiple
begin
if Threads[I].Suspended then
Threads[I].Resume
else
ShowMessage('Thread already in execution');
end;
end;

procedure TWorker.Execute;
var I: Integer;
J: Cardinal;

Ret: WideString;

A,B,C: Extended;
begin
CoInitialize(nil);
try
LoadDll;

while not Terminated do
begin
if not (Suspended or Terminated) then
begin
A := 310132041025;
B := 17592186044416;
C := 0;

for I:= 0 to 10 do
begin

if (Terminated) then begin
Break;
end;

for J:= 0 to 9999999 do
begin

if (Terminated) then begin
Break;
end;

A:= Sqrt(A);

if A <= 0 then begin
A:= 310132041025;
end
else begin
A:= Math.Power(A, 2);
end;

C:= C + (B-34 / 4);

B:= B / 2;

if B <= 0 then begin
B:= 17592186044416;
end;
end;

Ret := FEvalProcAddress(FEValValue);

NotifyMainForm(Format('Evaluate %s, resulted in %s', [IntToStr(I), Ret]));
end;
Suspend;
end;

Sleep(5000);
end;
finally
CoUninitialize;
end;
end;

procedure TWorker.LoadDll;
begin
//GlobalLock.Enter;
//try
FDLLHandle := LoadLibraryA(PChar(FPathApp + 'MyCalcFor32.dll'));
//finally
// GlobalLock.Leave;
//end;

if GetLastError <> 0 then
begin
NotifyTerminateThread;
end
else
begin
FEvalProcAddress := GetProcAddress(FDLLHandle, PChar('EVal'));

if GetLastError <> 0 then
begin
NotifyTerminateThread;
end;
end;
end;

当我只有 1 个线程时,它工作得很好,但是当我使用多个线程时它会引发以下异常:

System Error.  Code: 87.
Incorrect Parameter

注意:以上代码仅供复现;
我知道 WideString + AnsiString 问题。

最佳答案

您未正确执行错误检查。如果函数失败,您只能调用 GetLastError。我希望您在 API 调用成功后调用 GetLastError,而不是所有 API 调用在返回成功时都执行 SetLastError(0)。因此,您选择了一个不适用于您进行的函数调用的陈旧错误代码。

要检查失败,对于这些函数,您需要检查返回值。

  • LoadLibrary 通过返回 0 报告失败。
  • GetProcAddress 通过返回 nil 报告失败。

你必须仔细阅读函数的文档,但这是一个很常见的主题。每个 Win32 API 函数可能以不同的方式处理错误。分别阅读每个函数的文档。

关于windows - 如何在 Delphi 的多线程中加载一个 DLL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20566190/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com