Вопрос, поднятый пользователем, заключается в ошибке доступа к памяти (System.AccessViolationException), возникающей при вызове функции из DLL, написанной на Delphi XE2, из приложения на 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++) // больше итераций увеличивает вероятность сбоя
{
int threadCount = 10;
Parallel.For(1, threadCount, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, test =>
{
byte byteArgument = 42;
Test(byteArgument);
Console.WriteLine(String.Format("Итерация {0}: {1}", test, byteArgument));
});
}
}
Дополнительная информация указывает на то, что платформа - это x64 Windows 7, C# приложение компилируется для x86 в .NET 4.0, а DLL на Delphi компилируется для 32-битной архитектуры. Также отмечено, что аналогичная DLL, скомпилированная в MSVC, работает корректно с C# приложением, что предполагает специфику проблемы в использовании Delphi.
Решение проблемы:
Пользователь упоминает, что проблема не возникает, если функция не имеет возвращаемого значения и аргументов. Также было отмечено, что изменение соглашения о вызовах на cdecl не помогло.
Подтвержденный ответ от пользователя указывает на необходимость установки значения IsMultiThread в True в начале работы DLL. Это позволяет переключить менеджер памяти на многопоточный режим, который необходим для безопасной работы в многопоточной среде.
IsMultiThread := True;
Этот шаг решает проблему с ошибкой доступа к памяти в многопоточной среде.
Заключение
При работе с многопоточными вызовами функций из DLL, написанных на Delphi, важно учитывать настройки менеджера памяти. Установка IsMultiThread в True является ключевым решением для обеспечения корректной работы в многопоточной среде C# приложений.
Пользователь столкнулся с ошибкой доступа к памяти в C# при многопоточном вызове функций из DLL, скомпилированной на Delphi XE2, и нашёл решение в активации многопоточного менеджера памяти в DLL.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS