Некорректная Работа В Dll

Тема в разделе "Delphi - Компоненты", создана пользователем Shouldercannon, 2 янв 2012.

  1. Shouldercannon

    Shouldercannon Well-Known Member

    Регистрация:
    25 май 2010
    Сообщения:
    125
    Симпатии:
    0
    Project1 - первый прикреплённый *.pas
    DLL
    Код (Delphi):
    library dll;

    uses
    SysUtils,
    Windows,
    Dialogs,
    Controls,
    Unit1 in 'Unit1.pas' {Form1};

    {$R *.res}

    procedure ShowInfo(Win: Integer); stdcall;
    begin
    Form1[Win] := TForm1.Create(nil);
    Form1[Win].Show;
    end;

    function FormClosed(Win: Integer): Integer;
    begin
    if not Form1[Win].Visible then
    begin
    Form1[Win].Release;
    Result := 1;
    end
    else Result := 0;
    end;

    exports
    ShowInfo, FormClosed;

    begin
    end.
    Unit DLL - второй прикреплённый *.pas
    1. В DoTerminate выполняется только одно событие
    2. Прогресс бар при последующих закачках не двигается и вообще неправильно показывает прогресс
    3. Нулевая реакция на синхронизацию (написанные там события не выполняются)

    Тоже самое без DLL работает Великолепно. В чём проблема или это неизбежный косяк DLL?
     

    Вложения:

    • Unit1.pas
      Размер файла:
      2,2 КБ
      Просмотров:
      12
    • Unit1.pas
      Размер файла:
      4,7 КБ
      Просмотров:
      12
  2. sinkopa

    sinkopa Well-Known Member

    Регистрация:
    17 июн 2009
    Сообщения:
    344
    Симпатии:
    9
    А как Вы хотели... "здесь Вам не тут"... :)
    Использовать формы из DLL не так просто... Нет у меня сил лекцию читать, ищите соответствующую информацию в сети.
    Могу дать несколько замечаний.
    1. Никакого Application в DLL нету... Точнее ок есть как объект (раз уж в uses присутствует модуль Forms). Но он не инициализирован. Вы же не прописывали ему (Application) свойства ExeName и Handle? И Приложение (загрузившее DLL) тоже этого не делало (и не обязано). Так откудаж им взяться?
    Поэтому, чтобы DLL знала путь - нужно его передать через експортируемую процедуру (как параметр)... или же берите его из пути к самой DLL
    Код (Delphi):
    function DllSelfName(): string;
    var
    DllFileName: array[0..MAX_PATH] of Char;
    begin
    FillChar(DllFileName, SizeOf(DllFileName), #0);
    GetModuleFileName(hInstance, DllFileName, MAX_PATH);
    Result := StrPas(DllFileName);
    end;
    2. В DLL (с формами) главной проблемой как раз и является "поломанные" цепочки сообщений. В EXE за них отвечает Application который, как уже было сказано, (в DLL) не инициализирован.
    Частично ситуацию спасает принудительная инициализация Handle. Вот тут посмотрите примерчик:
    http://delphiworld.narod.ru/base/use_form_from_dll.html
    3. Synchronize(SyncProc); Делает следующее:
    - приостанавливает текущий потокж
    - передает управление основному потоку для выпонения кода который в SyncProc;
    Поскольку основным потоком у Вас является Приложение (всего лишь вызвавшее функцию внешней DLL) у меня к Вам вопрос:
    Как Вы считаете? А знает ли основной поток что нибудь про SyncProc? И наоборот - может ли поток рожденный в DLL что нибудь знать про основной поток? ;)
    4. Поскольку в DLL (как я уже сказал) у форм есть проблемы с цепочками сообщений, "слушальщик" формы может не получать Ваш PostMessage.
    Я не эксперементировал на эту тему, но возможно эти мессаги Вам придется ловить не "слушальщиком" а непосредственно в оконной процедуре окна. Можно еще попробовать передавать данные через метод формы Perform.
    5. Вы в курсе что SetWindowLong пересоздает окно? Почему не назначить дополнительные параметры на CreateParams формы?
    6. Почитал Ваш код еще раз... и честно говоря не понимаю, зачем вообще в данной "связке" (Одна форма/одна кнопка/одна загрузка) нужен еще и TDownLoader_Thread? Нельзя разве все выполнить на Button1Click? Неужели только из за того чтобы форма не подтормаживала? :)
    Ну так не проще разве в "критических" местах кода вставить Application.ProcessMessages;?
    Ну... в самом "тяжелом" случае... можно создавать поток единственной задачей которого будет "шевеление" прогрессбара... (например через критическую секцию) разве нет?
    У меня пока все...
    блин... один хрен лекция получилась... может мне в преподы надо было пойдти? :)
     
  3. Shouldercannon

    Shouldercannon Well-Known Member

    Регистрация:
    25 май 2010
    Сообщения:
    125
    Симпатии:
    0
    3. Судя из выше сказанного - не может.
    5. Теперь знаю. Код с
    Код (Delphi):
    SetWindowLong
    был написан не мной, трогать не стал.
    6.
    именно из-за этого. После долгий мучений решил так как есть. Пусть подтормаживает.

    Думаю, над этим стоит подумать, так как хорошо получается.
    P.S. Больше не буду пытаться делать что-либо в потоке в DLL.
     
Загрузка...
Похожие Темы - Некорректная Работа Dll
  1. Andrey Kha
    Ответов:
    0
    Просмотров:
    20
  2. Hoasker
    Ответов:
    0
    Просмотров:
    64
  3. garri671
    Ответов:
    0
    Просмотров:
    54
  4. lelik200969
    Ответов:
    0
    Просмотров:
    50
  5. Kozolick
    Ответов:
    0
    Просмотров:
    137

Поделиться этой страницей