I am calling a DLL function written in Delphi XE2 from C# using P/Invoke. It appears to be working when calls are made sequentially from a single thread. However, when multiple threads are calling the function, the C# host application throws System.AccessViolationException
seemingly at random.
Why does the code below trigger an access violation and how do I fix this?
Minimum Delphi library code for reproducing the problem:
library pinvokeproblem;
{$R *.res}
uses Windows, SysUtils;
procedure Test(const testByte: byte); stdcall;
begin
OutputDebugString(PWideChar(IntToStr(testByte)));
end;
exports Test;
end.
Minimum C# host application code to reproduce the problem:
[DllImport(
"pinvokeproblem.dll",
CallingConvention = CallingConvention.StdCall,
EntryPoint = "Test")]
private static extern void Test(byte testByte);
public static void Main(string[] args)
{
for (int i = 1; i <= 1000; i++) // more iterations = better chance to fail
{
int threadCount = 10;
Parallel.For(1, threadCount, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, test =>
{
byte byteArgument = 42;
Test(byteArgument);
Console.WriteLine(String.Format("Iteration {0}: {1}", test, byteArgument));
});
}
}
Additional information:
Platform is x64 Windows 7. C# host application built for x86 in .NET 4.0, Delphi DLL compiled for 32-bit.
The library appears to be working OK when used in a multi-threaded Delphi host application.
An MSVC version of the DLL with the function signature extern __declspec(dllexport) void __stdcall Test(char testByte)
works fine with the C# host (which suggests this is somehow specific to Delphi).
The code will not fail if the library function has no return value (void
) and arguments.
Changing the calling convention in both code to cdecl
did not help.
Any ideas would be much appreciated.
All you have to do is set IsMultiThread
to True
(as the first line in your DLL's main begin
..end
block) to switch the memory manager to a thread-safe mode:
IsMultiThread := True;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With