Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

### Ошибка 87 в Delphi: Проблемы с Подключением DLL в Многопоточной Среде

Delphi , Компоненты и Классы , Потоки

Ошибка 87 в Delphi: Проблемы с Подключением DLL в Многопоточной Среде

Разработчики, использующие Delphi для создания многопоточных приложений, могут столкнуться с ошибкой 87, когда пытаются загрузить библиотеку DLL в нескольких потоках. Эта проблема связана с неправильным управлением ресурсами и неправильной обработкой возвращаемых значений функций WinAPI. Давайте рассмотрим, как можно решить эту проблему.

Пример кода, вызывающего ошибку 87

В примере кода, предоставленном пользователем, есть несколько моментов, которые могут привести к ошибке 87. Например, функция загрузки DLL вызывается в каждом потоке отдельно, что может привести к конфликтам, если DLL уже загружена в адресном пространстве процесса.

procedure TWorker.LoadDll;
begin
  FDLLHandle := LoadLibraryA(PChar(FPathApp + 'MyCalcFor32.dll'));
  if GetLastError <> 0 then
  begin
    NotifyTerminateThread;
  end
  else
  begin
    FEvalProcAddress := GetProcAddress(FDLLHandle, PChar('EVal'));
    if GetLastError <> 0 then
    begin
      NotifyTerminateThread;
    end;
  end;
end;

Анализ проблемы

Проблема заключается в том, что GetLastError может возвращать устаревшую ошибку, которая не связана с последним выполненным действием. Кроме того, не все успешные вызовы функций сбрасывают GetLastError в 0. Необходимо проверять возвращаемые значения функций, а не GetLastError.

Решение проблемы

  1. Загрузка DLL один раз - загрузите DLL в основном потоке, а затем передайте дескриптор модуля в другие потоки.
  2. Проверка возвращаемых значений - проверяйте возвращаемые значения функций LoadLibrary и GetProcAddress, а не используйте GetLastError для определения успеха вызова.

Пример исправленного кода

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  // Создание потоков без загрузки DLL
end;

procedure TfrmMain.btnExecuteThreadsClick(Sender: TObject);
begin
  // Загрузка DLL в основном потоке
  FDLLHandle := LoadLibraryA(PChar(FPathApp + 'MyCalcFor32.dll'));
  if FDLLHandle = 0 then
  begin
    // Обработка ошибки
    ShowMessage('Не удалось загрузить DLL');
    Exit;
  end;
  FEvalProcAddress := GetProcAddress(FDLLHandle, PChar('EVal'));
  if FEvalProcAddress = nil then
  begin
    // Обработка ошибки
    FreeLibrary(FDLLHandle);
    ShowMessage('Не удалось получить адрес функции');
    Exit;
  end;

  // Передача информации о DLL в потоки
  for I := 0 to High(Threads) do
    Threads[I].DLLHandle := FDLLHandle;
    Threads[I].FEvalProcAddress := FEvalProcAddress;

  // Запуск потоков
  for I := 0 to High(Threads) do
    Threads[I].Resume;
end;

procedure TWorker.Execute;
begin
  // Использование переданных адресов функции
  Ret := FEvalProcAddress(FEValValue);
end;

procedure TWorker.Finalize;
begin
  if Assigned(FDLLHandle) then
    FreeLibrary(FDLLHandle);
end;

Заключение

При работе с многопоточными приложениями и загрузке DLL важно правильно управлять ресурсами и обрабатывать возвращаемые значения функций. Следуя приведенным рекомендациям, можно избежать ошибки 87 и других подобных проблем.

Создано по материалам из источника по ссылке.

Разработчики в Delphi сталкиваются с ошибкой 87 при попытке загрузки DLL в многопоточной среде из-за неправильного управления ресурсами и обработки возвращаемых значений функций WinAPI.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 13:56:27/0.0033960342407227/0