簡體   English   中英

在多線程環境中從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));
        });
     }
}

附加信息:

  • 平台是x64 Windows 7.在.NET 4.0中為x86構建的C#主機應用程序,為32位編譯的Delphi DLL。

  • 在多線程Delphi宿主應用程序中使用時,該庫似乎工作正常。

  • 帶有函數簽名extern __declspec(dllexport) void __stdcall Test(char testByte)的MSVC版本的extern __declspec(dllexport) void __stdcall Test(char testByte)與C#主機一起工作正常(這表明這是某種特定於Delphi的)。

  • 如果庫函數沒有返回值( void )和參數,代碼將不會失敗。

  • 將代碼中的調用約定更改為cdecl沒有幫助。

任何想法將不勝感激。

您所要做的就是將IsMultiThread設置為True (作為DLL的主要begin .. end塊中的第一行),以將內存管理器切換到線程安全模式:

IsMultiThread := True;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM