使用DLL和WideString

时间:2018-01-09 12:22:15

标签: delphi delphi-10.1-berlin

我遇到过以下问题: 当从多个线程并行调用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。

我做错了什么?

提前谢谢。

1 个答案:

答案 0 :(得分:2)

如果DLL应该在多线程环境中使用,那么在库的初始化部分中放置以下代码行:

IsMultiThread := True;