[英]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.