I have a dll and a test application written in Delphi. The test application uses multiple threads to call the function exported by the dll. The exported function has a trivial thread safe implementation. When running the test application various errors (access violation, invalid pointer operation, stack overflow etc) happens or the application freezes. In some cases the application finishes without errors.
Note that these errors only happen (surface) when using multiple threads. When calling the function from the main thread only then everything works fine.
I have found that adding ShareMem to both the dll and the application stops all these kind of errors. But I don't understand why. To my knowledge ShareMem is only needed when passing long strings between the dll and the application. As far as I know WideString is not a long string.
Also according to this post ShareMem should not be required: Why can Delphi DLLs use WideString without using ShareMem?
Here is the source of the dll:
library External;
uses
Winapi.Windows;
type
TMyType = class
private
FText: string;
end;
function DoSomething(input: WideString; out output: WideString): Bool; stdcall;
var
x: TObject;
begin
x := TMyType.Create;
try
output := x.ClassName;
finally
x.Free;
end;
Result := True;
end;
exports
DoSomething;
begin
end.
Here is the test application:
program ConsoleTest;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
Winapi.Windows,
OtlParallel;
function DoSomething(input: WideString; out output: WideString): Bool; stdcall; external 'External.dll' name 'DoSomething';
var
sResult: WideString;
begin
try
Parallel.&For(0, 500).Execute(procedure(value: Integer)
var
sResult: WideString;
begin
DoSomething('hhh', sResult);
end);
WriteLn('Done');
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Why ShareMem makes the bugs go away and is there another way to fix these bugs?
I am using Delphi XE2 and OmniThread 3.07.5.
Update - Same issue when run from a VCL application's button's on click event handler - If DoSomething uses a critical section inside then runs fine - If FText field is removed from TMyClass then no errors are reported but the application randomly freezes