在多线程环境中从 C# 调用 Delphi DLL 时发生访问冲突

Access violation when calling Delphi DLL from C# in a multi-threaded environment

我正在使用 P/Invoke 从 C# 中调用用 Delphi XE2 编写的 DLL 函数。当从单个线程按顺序进行调用时,它似乎可以正常工作。但是,当多个线程调用该函数时,C# 主机应用程序看似随机抛出 System.AccessViolationException

为什么下面的代码会触发访问冲突,我该如何解决?

重现问题的最小 Delphi 库代码:

library pinvokeproblem;

{$R *.res}

uses Windows, SysUtils;

procedure Test(const testByte: byte); stdcall;
begin
  OutputDebugString(PWideChar(IntToStr(testByte)));
end;

exports Test;

end.

重现问题的最低 C# 主机应用程序代码:

[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));
        });
     }
}

附加信息:

如有任何想法,我们将不胜感激。

您所要做的就是将 IsMultiThread 设置为 True(作为 DLL 主 begin..end 块中的第一行)以切换内存线程安全模式管理器:

IsMultiThread := True;