title: How to Load a DLL in multiple threads in Delphi?
body: <p>Maybe there is something that I missed, I can't figure what is happening here.</p>
  
  <p>I'm trying to load the same DLL in multiple instances of a TThread Object.</p>
  
  <p>Here is my DLL code:</p>
  
  
  
  <pre><code>library MyCalcFor32;
  
  uses
    SysUtils,
    Classes,
    uRunner in 'uRunner.pas';
  
  Exports EVal;
  
  {$R *.res}
  
  begin
  end.
  </code></pre>
  
  <p>This is the uRunner.pas:</p>
  
  
  
  <pre><code>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.
  </code></pre>
  
  <p>This is the program to Load the DLL:</p>
  
  <pre><code>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 &lt;= 0 then begin
                A:= 310132041025;
              end
              else begin
                A:= Math.Power(A, 2);
              end;
  
              C:= C + (B-34 / 4);
  
              B:= B / 2;
  
              if B &lt;= 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 &lt;&gt; 0 then
    begin
      NotifyTerminateThread;
    end
    else
    begin
      FEvalProcAddress := GetProcAddress(FDLLHandle, PChar('EVal'));
  
      if GetLastError &lt;&gt; 0 then
      begin
        NotifyTerminateThread;
      end;
    end;
  end;
  </code></pre>
  
  <p>When I have only 1 thread, it works just fine, but when I use multiple threads It raises the following exception:</p>
  
  <pre><code>System Error.  Code: 87.
  Incorrect Parameter
  </code></pre>
  
  <p>Note: The above code is just for reproduction; <br>
        I am aware of WideString + AnsiString problem.</p>