gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 18:26:45 24 4
gpt4 key购买 nike

我正在使用 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 主机应用程序中使用时,该库似乎工作正常。

  • 具有函数签名的 DLL 的 MSVC 版本 extern __declspec(dllexport) void __stdcall Test(char testByte) 在 C# 主机上运行良好(这表明这在某种程度上特定于 Delphi ).

  • 如果库函数没有返回值(void)和参数,代码不会失败。

  • 将两个代码中的调用约定更改为 cdecl 没有帮助。

任何想法将不胜感激。

最佳答案

您只需设置 IsMultiThreadTrue(作为 DLL 主 begin..end block 中的第一行)将内存管理器切换到线程安全模式:

IsMultiThread := True;

关于c# - 在多线程环境中从 C# 调用 Delphi DLL 时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30189570/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com