Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создать поток ИЗ DLL, или работа dll без формы 
:(
    Опции темы
Domoffou
Дата 22.6.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Здравствуйте.
Пишу программу прямо в dll, ей ничего не нужно будет, кроме как просто loadlibrary из другого приложения.
В ДЛЛ необходимо использовать таймеры и потоки (как в обычном приложении),
т.к. в ней будет стоять хук и по определенным фразам необходимо делать скриншот и выполнять другие определенные действия,
поэтому если все действия будут не в потоке, то полагаю клава подвиснет.
Пытался создать в DLL отдельный поток, как в программе, но он вылетает с ошибкой по методу execute
Приведу пример:
Код


library Bugaga;

uses
  Windows,
  SysUtils,
  Messages,
  Classes,
  TlHelp32;

TBugagaThread = class(tthread)
  private
    { private declarations }
  protected
    procedure execute; override;
  end;

procedure TBugagaThread.execute;
begin
sleep(1000);
MessageBox(0, 'Hello world!',
'DLL Message Box', MB_OK or MB_ICONEXCLAMATION); 
end;

procedure BugagaStart;
var
  new: TBugagaThread;
begin
  new:=TBugagaThread.Create(true);
  new.freeonterminate := true;
  new.priority := tplowest;
  new.resume;        // <-- ВОТ ЕСЛИ ЭТО ЗАКОМЕНТИРОВАТЬ, ТО ПРОГРАММА НЕ ВЫЛЕТАЕТ!!!!!!!!!
end;

// При загрузке DLL
begin
BugagaStart;        // <-- Происходит после LoadLibrary из другого приложения
end.


Т.е. если происходит запуск потока, то библиотеке это не нравится.
Соответственно вопрос, как организовать потоки прямо в dll?

Это сообщение отредактировал(а) Domoffou - 22.6.2008, 22:30
PM MAIL ICQ   Вверх
Cashey
Дата 23.6.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: нет
Всего: 60



Цитата(Domoffou @  22.6.2008,  23:29 Найти цитируемый пост)
MessageBox(0, 'Hello world!',
'DLL Message Box', MB_OK or MB_ICONEXCLAMATION); 

как минимум MessageBox из потока вызывать нельзя


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Rrader
  Дата 23.6.2008, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Cashey, почему?


Domoffou, случайно не так делаешь? smile 
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  H: THandle;
begin
  H := LoadLibrary('Bugaga.dll');
  FreeLibrary(H);
end;



--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Cashey
Дата 23.6.2008, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: нет
Всего: 60



Цитата(Rrader @  23.6.2008,  11:01 Найти цитируемый пост)
Cashey, почему?

потому что, обращение к ресурсу из потока может осуществлятся только через метод Synchronize


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
MetalFan
  Дата 23.6.2008, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(Cashey @  23.6.2008,  10:30 Найти цитируемый пост)
потому что, обращение к ресурсу из потока может осуществлятся только через метод Synchronize

к какому ресурсу???
по идее никакой ошибки Windows.MessageBox вызывать не должен в  случае вызова из потока, НО:
Цитата(MSDN)
Dynamic-Link Library Entry-Point Function
...
Calling other functions may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary to load other system components. Conversely, calling those functions during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.


Это сообщение отредактировал(а) MetalFan - 23.6.2008, 12:19


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Cashey
Дата 23.6.2008, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: нет
Всего: 60



Цитата(MetalFan @  23.6.2008,  12:50 Найти цитируемый пост)
к какому ресурсу???
по идее никакой ошибки Windows.MessageBox вызывать не должен в  случае вызова из потока

да? ну вызыве мессэйдж из потока, а я посмотрю


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Rrader
  Дата 23.6.2008, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 29
Всего: 191



Cashey, Synchronize предназначен для безопасного вызова метода, обычно работающего с VCL, или там, где требуется сложная синхронизация. В данном случае VCL вообще не используется.

MessageBox <> TApplication.MessageBox;

Вызывать можно без синхронизации.

Код

unit UTest;

interface

uses
  Classes, Windows;

type
  TMyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

{ TMyThread }

procedure TMyThread.Execute;
begin
  MessageBox(0, 'Text', 'Caption', MB_OK);
end;

end.


Это сообщение отредактировал(а) Rrader - 22.7.2008, 14:42


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
MetalFan
Дата 23.6.2008, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



да легко! в чем проблема то? вызывается все прекрасно! (подчеркну - именно Windows.MessageBox, а не Dialogs.MessageDlg)


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Cashey
Дата 24.6.2008, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: нет
Всего: 60



Цитата(MetalFan @  23.6.2008,  17:19 Найти цитируемый пост)
(подчеркну - именно Windows.MessageBox, а не Dialogs.MessageDlg) 

все, извеняюсь, попутал с ShowMessage


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Domoffou
Дата 24.6.2008, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Все в порядке, Господа smile
проблему удалось решить несколько иначе.
Ошибка возникала потому, что при инициализации DLL запрещены некоторые действия (в т.ч. создание потоков),
поэтому создавал потоки я позже, после загрузки DLL.
А MessageBox вызывается нормально smile
PM MAIL ICQ   Вверх
Riply
Дата 25.6.2008, 01:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Domoffou @  24.6.2008,  17:07 Найти цитируемый пост)
Ошибка возникала потому, что при инициализации DLL запрещены некоторые действия (в т.ч. создание потоков),


А откуда информация что "при инициализации DLL запрещено  создание потоков" ?
IMHO,  зависит от того как создавать поток (например, не стоит использовать SysUtils).

PM MAIL   Вверх
dumb
Дата 25.6.2008, 03:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



Цитата(Best Practices for Creating DLLs)

You should never perform the following tasks from within DllMain:

  •  Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
  •  Synchronize with other threads. This can cause a deadlock.
  •  Acquire a synchronization object that is owned by code that is waiting to acquire the loader lock. This can cause a deadlock.
  •  Initialize COM threads by using CoInitializeEx. Under certain conditions, this function can call LoadLibraryEx.
  •  Call the registry functions. These functions are implemented in Advapi32.dll. If Advapi32.dll is not initialized before your DLL, the DLL can access uninitialized memory and cause the process to crash.
  •  Call CreateProces. Creating a process can load another DLL.
  •  Call ExitThread. Exiting a thread during DLL detach can cause the loader lock to be acquired again, causing a deadlock or a crash.
  •  Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
  •  Create a named pipe or other named object (Windows 2000 only). In Windows 2000, named objects are provided by the Terminal Services DLL. If this DLL is not initialized, calls to the DLL can cause the process to crash.
  •  Use the memory management function from the dynamic C Run-Time (CRT). If the CRT DLL is not initialized, calls to these functions can cause the process to crash.
  •  Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.
  •  Use managed code.

 
The following tasks are safe to perform within DllMain:

  •  Initialize static data structures and members at compile time.
  •  Create and initialize synchronization objects.
  •  Allocate memory and initialize dynamic data structures (avoiding the functions listed above.)
  •  Set up thread local storage (TLS).
  •  Open, read from, and write to files.
  •  Call functions in Kernel32.dll (except the functions that are listed above).
  •  Set global pointers to NULL, putting off the initialization of dynamic members. In Microsoft Windows Vista™, you can use the one-time initialization functions to ensure that a block of code is executed only once in a multithreaded environment.

Best Practices for Creating DLLs (doc)
PM MAIL   Вверх
Riply
Дата 25.6.2008, 05:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



dumb, 

Хм... Как-то я ухитрилась пропустить этот момент раньше. Спасибо.

Очень жаль что не расписали почему рискованно.

P.S. 
 У меня пара проектов довольно давно и довольно успешно работает .
 В них используется BeginThread в DllMain. Причем один из них "работает из App_InitDll" (если правильно запомнила имя).
 Я понимаю, что BeginThread вызывает CreateThread, но может в этом причина их "не падений" ?
 
PM MAIL   Вверх
CodeMonkey
Дата 25.6.2008, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата(Domoffou @  24.6.2008,  17:07 Найти цитируемый пост)
Ошибка возникала потому, что при инициализации DLL запрещены некоторые действия (в т.ч. создание потоков)

Цитата(Riply @  25.6.2008,  05:22 Найти цитируемый пост)
У меня пара проектов довольно давно и довольно успешно работает .


Создание потоков в DllMain не запрещено. Оно просто не рекомендуется, т.к. может привести к взаимной блокировке. 
Подробно что, как и почему можно посмотреть, например, здесь: Best Practices for Creating DLLs (http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx - справа пункт Download).



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Domoffou
Дата 6.7.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Блин, теперь другая проблема но из той же темы :(
Делаю так:
1. открываю DLL
2. запускаю форму из нее
3. при FormCreate делаю:
Код

test := BeginThread(nil, 0, @bugaga, nil, 0, th1);


в свою очередь:
Код

procedure bugaga;
begin
MessageBox(0, PAnsiChar('eeeeeeeeeeeee'),PChar('ok'),+MB_ICONERROR+MB_DEFBUTTON1);
end;

что самое интересное, поток создается только в тот момент, когда я закрываю форму, созданную из DLL.

Подскажите, пожалуйста, что не так.

Это сообщение отредактировал(а) Domoffou - 6.7.2008, 19:06
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0640 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.