Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 04:44
Оценка:
очень простой пример. реализация клавиатурного хука через dll.

library Hook;
uses Windows, SysUtils, dialogs;
var
myHook: HHook = 0;
w1: longint =44;


function MsgProc(Code: integer; wParam: Word; lParam: Longint): Longint; stdcall;
begin
if (Code = HC_ACTION) and (((lParam shr 16) and KF_UP) = 0) then
begin
showmessage(inttostr(w1));
result := 1;
end else result := CallNextHookEx(0, Code, wParam, lParam);
end;

procedure setHook(Hook: boolean) stdcall;
begin
if Hook then
if myHook = 0 then myHook := SetWindowsHookEx(WH_KEYBOARD, @MsgProc, HInstance, 0)
else
begin
if myHook <> 0 then UnHookWindowsHookEx(myHook);
myHook := 0;
end;
end;
procedure start; stdcall;
begin
w1:=555555;
end;


exports setHook name 'SetHook', start name 'start';

begin
end.


в программе грузится статически.
procedure setHook(Hook: boolean) stdcall; external 'hook.dll' name 'SetHook';
procedure start; stdcall; external 'hook.dll' name 'start';
из программы при onshow идет start и потом sethook.
процедура start выполняется один раз при запуске программы. происходит присвоение глобальной переменной w1.

внимание вопрос.
когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
но когда без фокуса начальное значение переменной 44.
почему?
Re: Глобальная переменная в dll
От: Аноним  
Дата: 17.11.10 06:28
Оценка:
jcp>внимание вопрос.
jcp>когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
jcp>но когда без фокуса начальное значение переменной 44.
jcp>почему?

Потому, что у процесса, в контексте которого выполняется MsgProc переменная w1 не инициализирована (содержит мусор который компилятор записал в файл). Кратко: между процессами разделяется только код длл, но не данные.
Re[2]: Глобальная переменная в dll
От: Аноним  
Дата: 17.11.10 14:14
Оценка:
Здравствуйте, Аноним, Вы писали:

jcp>>внимание вопрос.

jcp>>когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
jcp>>но когда без фокуса начальное значение переменной 44.
jcp>>почему?

А>Потому, что у процесса, в контексте которого выполняется MsgProc переменная w1 не инициализирована (содержит мусор который компилятор записал в файл). Кратко: между процессами разделяется только код длл, но не данные.



как же быть, если нужно в msgproc использовать данные ?
Re: Глобальная переменная в dll
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 15:12
Оценка:
нифига не понятно. Почему w1:=555555; зашито в коде? чем это тогда отличается от константы?
и почему при установке хука значение не передавать?
Re[2]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 15:19
Оценка:
Здравствуйте, Clickmaker, Вы писали:

C>нифига не понятно. Почему w1:=555555; зашито в коде? чем это тогда отличается от константы?

C>и почему при установке хука значение не передавать?

Нет блин я буду всю процедуру записи в w1 писать. все сократил по максимуму. оставив главное. когда w1 константа
все прекрасно пашет.
смею заметить что запись в эту переменную происходит при загрузке. до установки хука.
Re[3]: Глобальная переменная в dll
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 15:42
Оценка:
Здравствуйте, jcp, Вы писали:

jcp>Здравствуйте, Clickmaker, Вы писали:


C>>нифига не понятно. Почему w1:=555555; зашито в коде? чем это тогда отличается от константы?

C>>и почему при установке хука значение не передавать?

jcp>Нет блин я буду всю процедуру записи в w1 писать. все сократил по максимуму. оставив главное. когда w1 константа

jcp> все прекрасно пашет.
jcp>смею заметить что запись в эту переменную происходит при загрузке. до установки хука.

а так не пойдет?

function MsgProc(Code: integer; wParam: Word; lParam: Longint): Longint; stdcall;
begin
if w1 = -1 then begin
w1 := вычисляем w1
end;
...
end;
Re[4]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 17:45
Оценка:
Здравствуйте, Clickmaker, Вы писали:

C>Здравствуйте, jcp, Вы писали:


jcp>>Здравствуйте, Clickmaker, Вы писали:


C>>>нифига не понятно. Почему w1:=555555; зашито в коде? чем это тогда отличается от константы?

C>>>и почему при установке хука значение не передавать?

jcp>>Нет блин я буду всю процедуру записи в w1 писать. все сократил по максимуму. оставив главное. когда w1 константа

jcp>> все прекрасно пашет.
jcp>>смею заметить что запись в эту переменную происходит при загрузке. до установки хука.

C>а так не пойдет?


C>function MsgProc(Code: integer; wParam: Word; lParam: Longint): Longint; stdcall;

C>begin
C> if w1 = -1 then begin
C> w1 := вычисляем w1
C> end;
C> ...
C>end;


понимаете зачем я делал это раздельно.
есть процедура старт. там в глобальные переменные записываются данные из ини файла.
потом с этим данными идет работа.
считать их за один раз, с точки зрения оптимизации, лучше, чем постояно при каждом нажатии на клавишу.
Re[3]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 17:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


jcp>>>внимание вопрос.

jcp>>>когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
jcp>>>но когда без фокуса начальное значение переменной 44.
jcp>>>почему?

А>>Потому, что у процесса, в контексте которого выполняется MsgProc переменная w1 не инициализирована (содержит мусор который компилятор записал в файл). Кратко: между процессами разделяется только код длл, но не данные.



А>как же быть, если нужно в msgproc использовать данные ?




да и еще кстати, если данные не разделяются, но константы то работают.
Re[3]: Глобальная переменная в dll
От: Pavel Dvorkin Россия  
Дата: 17.11.10 17:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


jcp>>>внимание вопрос.

jcp>>>когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
jcp>>>но когда без фокуса начальное значение переменной 44.
jcp>>>почему?

А>>Потому, что у процесса, в контексте которого выполняется MsgProc переменная w1 не инициализирована (содержит мусор который компилятор записал в файл). Кратко: между процессами разделяется только код длл, но не данные.



А>как же быть, если нужно в msgproc использовать данные ?


Не знаю, как в Дельфи, но в MS VC++ есть такая штука — #pragma dataseg, которая позволяет сделать shared секцию в DLL. Эта shared секция одна на все процессы, в которые загружена эта DLL.

http://www.rsdn.ru/forum/delphi/14198.all.aspx
Автор: Studiosus
Дата: 25.11.01
With best regards
Pavel Dvorkin
Re[4]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 18:16
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Аноним, Вы писали:


jcp>>>>внимание вопрос.

jcp>>>>когда приложение, которое вызвало эту длл в фокусе, showmessage w1 показывает нужное значение 555555,
jcp>>>>но когда без фокуса начальное значение переменной 44.
jcp>>>>почему?

А>>>Потому, что у процесса, в контексте которого выполняется MsgProc переменная w1 не инициализирована (содержит мусор который компилятор записал в файл). Кратко: между процессами разделяется только код длл, но не данные.



А>>как же быть, если нужно в msgproc использовать данные ?


PD>Не знаю, как в Дельфи, но в MS VC++ есть такая штука — #pragma dataseg, которая позволяет сделать shared секцию в DLL. Эта shared секция одна на все процессы, в которые загружена эта DLL.


PD>http://www.rsdn.ru/forum/delphi/14198.all.aspx
Автор: Studiosus
Дата: 25.11.01




спасибо, попробую. в делфи тоже есть такое.
Re[4]: Глобальная переменная в dll
От: Аноним  
Дата: 17.11.10 18:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Не знаю, как в Дельфи, но в MS VC++ есть такая штука — #pragma dataseg, которая позволяет сделать shared секцию в DLL. Эта shared секция одна на все процессы, в которые загружена эта DLL.


Нету у дельфей такого. Предлагал пару лет назад на QC, сделать чтонить типа sharedvar, сказали некактуально Выход — шарить данные при помощи MMF. Хост процесс создает файл, длл открывает его в DLL_PROCESS_ATTACH.
Re[5]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 18:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Не знаю, как в Дельфи, но в MS VC++ есть такая штука — #pragma dataseg, которая позволяет сделать shared секцию в DLL. Эта shared секция одна на все процессы, в которые загружена эта DLL.


А>Нету у дельфей такого. Предлагал пару лет назад на QC, сделать чтонить типа sharedvar, сказали некактуально Выход — шарить данные при помощи MMF. Хост процесс создает файл, длл открывает его в DLL_PROCESS_ATTACH.



если уж морочицо с шаред секцией, проще мою длл скомпилировать на vc ))) есть еще идеи ?
Re[6]: Глобальная переменная в dll
От: Аноним  
Дата: 17.11.10 18:51
Оценка:
Здравствуйте, jcp, Вы писали:

jcp>если уж морочицо с шаред секцией, проще мою длл скомпилировать на vc ))) есть еще идеи ?


гуглить статью "Hooks — аспекты реализации"
Re[7]: Глобальная переменная в dll
От: jcp  
Дата: 17.11.10 19:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, jcp, Вы писали:


jcp>>если уж морочицо с шаред секцией, проще мою длл скомпилировать на vc ))) есть еще идеи ?


А>гуглить статью "Hooks — аспекты реализации"





спасибо друзья. сделал с mmf
Re[5]: Глобальная переменная в dll
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 20:38
Оценка:
jcp>считать их за один раз, с точки зрения оптимизации, лучше, чем постояно при каждом нажатии на клавишу.

там проверочка есть if w1 = -1. как раз, чтобы считать один раз. Ну по разу на процесс, хорошо, но не каждое нажатие.
Re[6]: Глобальная переменная в dll
От: jcp  
Дата: 18.11.10 04:25
Оценка:
Здравствуйте, Clickmaker, Вы писали:

jcp>>считать их за один раз, с точки зрения оптимизации, лучше, чем постояно при каждом нажатии на клавишу.


C>там проверочка есть if w1 = -1. как раз, чтобы считать один раз. Ну по разу на процесс, хорошо, но не каждое нажатие.


скомпилируй мой код, глянь, этот подход не рабочий. при каждом нажатии вне приложения будет w1 44 тк я задавал значение явно,
если убрать 44 то w1 будет 0. при каждом нажатии. проблему я решил. ответил выше. с помощью mmf
Re[7]: Глобальная переменная в dll
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 18.11.10 08:30
Оценка:
jcp>скомпилируй мой код, глянь, этот подход не рабочий. при каждом нажатии вне приложения будет w1 44 тк я задавал значение явно,
jcp>если убрать 44 то w1 будет 0. при каждом нажатии. проблему я решил. ответил выше. с помощью mmf

да почему не рабочий?
сначала w1 имеет значение 0 (если не указано явно), при загрузке хука процессом и первом нажатии проверяем: если 0, вычислили, сохранили.
При втором нажатии там уже не 0, поскольку dll уже в адресном пространстве процесса и глобальная переменная живет. Значит, повторно не вычисляем.
Re[8]: Глобальная переменная в dll
От: jcp  
Дата: 18.11.10 09:31
Оценка:
Здравствуйте, Clickmaker, Вы писали:

jcp>>скомпилируй мой код, глянь, этот подход не рабочий. при каждом нажатии вне приложения будет w1 44 тк я задавал значение явно,

jcp>>если убрать 44 то w1 будет 0. при каждом нажатии. проблему я решил. ответил выше. с помощью mmf

C>да почему не рабочий?

C>сначала w1 имеет значение 0 (если не указано явно), при загрузке хука процессом и первом нажатии проверяем: если 0, вычислили, сохранили.
C>При втором нажатии там уже не 0, поскольку dll уже в адресном пространстве процесса и глобальная переменная живет. Значит, повторно не вычисляем.

проверял на практике?
Re[9]: Глобальная переменная в dll
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 18.11.10 10:04
Оценка:
jcp>проверял на практике?
что тут проверять? каждый процесс имеет свою копию глобальных переменных в dll. При первом срабатывании хука достаточно один раз их проинициализировать.
Проблема может возникнуть, если данные нужно разделять именно между процессами. Если это твой случай — ну тогда сорри, неверно понял задачу
Re[10]: Глобальная переменная в dll
От: jcp  
Дата: 18.11.10 14:12
Оценка:
Здравствуйте, Clickmaker, Вы писали:

jcp>>проверял на практике?

C>что тут проверять? каждый процесс имеет свою копию глобальных переменных в dll. При первом срабатывании хука достаточно один раз их проинициализировать.
C>Проблема может возникнуть, если данные нужно разделять именно между процессами. Если это твой случай — ну тогда сорри, неверно понял задачу

конешно же ты прав.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.