[英]How to Load a DLL in multiple threads in Delphi?
也許有些東西我錯過了,我不知道這里發生了什么。
我正在嘗試在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函數可能會以不同的方式處理錯誤。 分別閱讀每個功能的文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.