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

Проблемы с работой формы в DLL в Delphi 12: почему компоненты не работают через rundll32.exe и как это исправить?

Delphi , Технологии , COM и DCOM

Проблемы с работой формы в DLL в Delphi 12: почему компоненты не работают через rundll32.exe и как это исправить?

Разработка DLL-библиотек с графическим интерфейсом в Delphi всегда была сопряжена с особенностями, а в версии 12 Athens многие разработчики столкнулись с новыми проблемами при использовании форм через rundll32.exe. В этой статье разберем типичные ошибки и предоставим рабочие решения.

Проблема: компоненты формы не работают через rundll32.exe

Пользователь Anna Blanca столкнулась с ситуацией, где её DLL с формой корректно работала в Delphi 11, но перестала функционировать в Delphi 12 при запуске через rundll32.exe. Код выглядел так:

procedure Start;
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm := False;
  Application.Run;
end;

exports
  Start;

После перехода на Delphi 12 компоненты формы перестали реагировать на события, хотя при запуске через основное приложение всё работало.

Причина: нарушение соглашения вызова для rundll32

Remy Lebeau правильно указал на ключевую ошибку: функция, экспортируемая в DLL для rundll32, должна строго соответствовать сигнатуре, ожидаемой Windows:

procedure Start(
  hwnd: HWND; 
  hinst: HINST; 
  lpszCmdLine: PAnsiChar; 
  nCmdShow: Integer
); stdcall;

В Delphi 11 код мог работать "случайно" благодаря особенностям управления памятью, но в версии 12 Athens Embarcadero ужесточила требования к совместимости.

Исправленный код экспортируемой функции:

uses
  Winapi.Windows, System.SysUtils;

procedure Start(
  hwnd: HWND; 
  hinst: HINST; 
  lpszCmdLine: PAnsiChar; 
  nCmdShow: Integer
); stdcall;
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm := False;
  Application.Run;
end;

exports
  Start;

Важно! Тип HINST объявлен в модуле System. Если IDE подчеркивает его красным, добавьте Winapi.Windows в uses.

Дополнительная проблема: создание COM-объектов в DLL

Anna также столкнулась с проблемой создания ярлыков (.lnk) через IShellLink. Код работал в EXE, но не в DLL при запуске через rundll32.

Причина: COM не был инициализирован. В отличие от VCL-приложения, где CoInitialize вызывается автоматически, в DLL это нужно делать вручную.

Исправленный код с инициализацией COM:

procedure Start(...); stdcall;
begin
  // Инициализация COM для текущего потока
  if Failed(CoInitializeEx(nil, COINIT_MULTITHREADED)) then
    Exit;

  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.ShowMainForm := False;
    Application.Run;
  finally
    CoUninitialize; // Важно для очистки COM
  end;
end;

Корректное создание ярлыка в форме:

uses
  System.IOUtils, Winapi.ShlObj, Winapi.ActiveX;

procedure TForm1.CreateLink(const PathObj, PathLink, Desc, Param: String);
var
  IObject: IUnknown;
  SLink: IShellLink;
  PFile: IPersistFile;
begin
  IObject := CreateComObject(CLSID_ShellLink);
  OleCheck(IObject.QueryInterface(IShellLink, SLink));
  OleCheck(IObject.QueryInterface(IPersistFile, PFile));

  OleCheck(SLink.SetPath(PChar(PathObj)));
  OleCheck(SLink.SetDescription(PChar(Desc)));
  OleCheck(SLink.SetArguments(PChar(Param)));

  OleCheck(PFile.Save(PWideChar(PathLink), False));
end;

Совет: Всегда используйте OleCheck для обработки ошибок COM.

Почему в EXE работало, а в DLL — нет?

  1. Управление памятью: В EXE VCL автоматически инициализирует COM и создает контекст для форм.
  2. Контекст выполнения: rundll32.exe не предназначен для запуска GUI через DLL. Это "хак", который требует ручной настройки.
  3. Версии Delphi: Начиная с Delphi 12, RTL стал строже относиться к соглашениям вызова и инициализации модулей.

Альтернативное решение: используйте отдельный EXE-загрузчик

Если вам критично нужно стабильное GUI в библиотеке, рассмотрите архитектуру с двумя модулями:
1. DLL — содержит бизнес-логику.
2. EXE-загрузчик — вызывает DLL и создает формы.

// В DLL
procedure ShowForm; stdcall;
begin
  Form1 := TForm1.Create(nil);
  try
    Form1.ShowModal;
  finally
    Form1.Free;
  end;
end;

// В EXE
procedure TLoaderForm.Button1Click(Sender: TObject);
var
  LibHandle: HMODULE;
  ShowFormProc: procedure; stdcall;
begin
  LibHandle := LoadLibrary('MyGuiLib.dll');
  if LibHandle <> 0 then
  begin
    @ShowFormProc := GetProcAddress(LibHandle, 'ShowForm');
    if Assigned(ShowFormProc) then
      ShowFormProc();
    FreeLibrary(LibHandle);
  end;
end;

Отладка DLL в Delphi IDE

Чтобы отладить DLL, запускаемую через rundll32:
1. В меню выберите Run > Parameters.
2. В поле Host Application укажите путь к rundll32.exe (обычно C:\Windows\System32\rundll32.exe).
3. В Parameters укажите вашу DLL и функцию: MyLib.dll,Start.
4. Установите точки останова и запустите проект (F9).

Заключение

Проблемы с формами в DLL в Delphi 12 возникают из-за ужесточения требований к совместимости и инициализации.

Ключевые моменты для исправления:
1. Соблюдайте точную сигнатуру функций для rundll32.
2. Всегда инициализируйте COM вручную в DLL.
3. Используйте CoInitializeEx/CoUninitialize в паре.
4. Рассмотрите альтернативные архитектуры с EXE-загрузчиком.

Примеры кода из статьи можно адаптировать под ваши задачи. Помните, что использование rundll32 для GUI — нестандартный сценарий, поэтому всегда тестируйте поведение в целевых версиях Windows.

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

Проблемы с работой форм в DLL в Delphi 12 из-за неправильной сигнатуры функций и отсутствия инициализации COM, и способы их решения.


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

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




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


:: Главная :: COM и DCOM ::


реклама


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

Время компиляции файла: 2024-12-22 17:14:06
2026-06-29 18:44:26/0.0040340423583984/0