我遇到过以下问题: 当从多个线程并行调用DLL函数时,我得到“EAggregateException:发生了一个或多个错误”。
最小的DLL示例是:
library MyDLL;
uses
System.SysUtils;
procedure MyUpper(const ASource: WideString; out AResult: WideString); stdcall;
begin
AResult := String(ASource).ToUpper;
end;
exports
MyUpper;
end.
使用它的应用程序:
program MyEXE;
uses
System.SysUtils,
System.Threading;
procedure MyUpper(const AText: WideString; out AResult: WideString); stdcall; external 'MyDLL.dll';
procedure Test;
var
LLoop: TParallel.TLoopResult;
LSync: IReadWriteSync;
begin
LSync := TSimpleRWSync.Create;
LLoop := TParallel.&For(1, 100000,
procedure (AIndex: Integer)
var
LResult: WideString;
begin
MyUpper(AIndex.ToString, LResult);
end);
Writeln('Completed: ', LLoop.Completed);
end;
begin
try
Test;
except
on E: Exception do
Writeln(E.ClassName + ': ' + E.Message);
end;
Readln;
end.
如果在EXE中,我写下以下内容:
AResult := ASource;
然后执行成功。但是一旦我使用任何隐式/显式字符串转换,它就会失败。怎么会这样?每个线程使用它的本地堆栈调用此方法作为常规方法,并且没有共享变量(至少可见)。
我不使用任何共享内存管理器,因为我将使用不同编程语言的DLL。
我做错了什么?
提前谢谢。
答案 0 :(得分:2)
如果DLL应该在多线程环境中使用,那么在库的初始化部分中放置以下代码行:
IsMultiThread := True;