C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 02-07-2010, 07:28 AM   #1
Registered User
 
Join Date: Nov 2007
Posts: 11
DLL global value ...

Hello!

I have a keyboard global hook in dll and a dialog that uses that hook. Hook is inspecting input for a certain key combination and on detection does a SendMessage to my dialog box. Now, problem is that when dialog loses focus, hook doesn't work no more. I assume that DLL embedded in memory space of the process with focus has "new" stack which does not contain dialog's handler, obviously. So, the question is how to maintain my dialog's handle in DLL globally? I could dump it to a file, but that's just ugly. Maybe something like a "reversed atom", where I could use literal string to locate HINSTANCE value in any process space or something like that? Any ideas? Thank you!
xlines is offline   Reply With Quote
Old 02-07-2010, 02:36 PM   #2
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,814
The dialog must be part of the DLL or you must expose a way in the DLL interface to get the value the dialog relies on. Each DLL has its own CRT. There are ways to share data across DLLs/modules/processes using DDE (Dynamic Data Exchange) in Win32 but I do not have much experience with it.

As a general rule statics and globals in DLLs cannot be accessed or used by other modules.
__________________
If you aim at everything you will hit something but you won't know what it is.

Last edited by Bubba; 02-07-2010 at 02:44 PM.
Bubba is offline   Reply With Quote
Old 02-07-2010, 04:24 PM   #3
Registered User
 
Join Date: Nov 2007
Posts: 11
Quote:
Originally Posted by Bubba View Post
The dialog must be part of the DLL or you must expose a way in the DLL interface to get the value the dialog relies on. Each DLL has its own CRT. There are ways to share data across DLLs/modules/processes using DDE (Dynamic Data Exchange) in Win32 but I do not have much experience with it.

As a general rule statics and globals in DLLs cannot be accessed or used by other modules.
Well I really need this global variable. Two approaches emerged from googling: mapped file and shared/read/write page. Mapped file sure looks like a safer and less hard-coded solution, so I'll go with that. Thank you for answering!
xlines is offline   Reply With Quote
Old 02-07-2010, 04:46 PM   #4
Registered User
 
Join Date: Jan 2010
Posts: 230
Memory mapped files and shared memory are the same thing, except that for shared memory your mapped "file" is a virtual memory area in the paging file and not a real physical file.
See Creating Named Shared Memory (Windows) for a simple example of shared memory.

Personally I would use shared memory mapping for temporary data and file mapping for data that needs to be saved between executions, but either way would work just as good for this task.
_Mike is offline   Reply With Quote
Old 02-07-2010, 05:21 PM   #5
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,900
Or you could use WH_KEYBOARD_LL, which is always called within the context of your own app (no dll injection).

gg
Codeplug is offline   Reply With Quote
Old 02-07-2010, 05:37 PM   #6
Registered User
 
Join Date: Nov 2007
Posts: 11
Quote:
Originally Posted by Codeplug View Post
Or you could use WH_KEYBOARD_LL, which is always called within the context of your own app (no dll injection).
gg
Say what? Now, that's ... interesting. And an elegant solution to my problem. What's the catch, what's the downside?
xlines is offline   Reply With Quote
Old 02-08-2010, 08:27 AM   #7
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,900
I only know the differences as documented on MSDN.
LowLevel:
- requires a message loop
- doesn't get a "repeat count" (assuming all strokes invoke callback)
- callback must be fast to prevent system from automatically calling next hook (if you want to absorb the stroke completely)
- can detect injected strokes
etc...

gg
Codeplug is offline   Reply With Quote
Old 02-08-2010, 11:41 PM   #8
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,814
Why can't you just expose the global variable via a C or C++ function in the DLL? This seems the simplest solution to me. Shared memory is not something I would use for such little data being shared - especially given all the new requirements and caveats it brings in.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 02-09-2010, 02:23 AM   #9
Registered User
 
Join Date: Nov 2007
Posts: 11
Quote:
Originally Posted by Bubba View Post
Why can't you just expose the global variable via a C or C++ function in the DLL? This seems the simplest solution to me. Shared memory is not something I would use for such little data being shared - especially given all the new requirements and caveats it brings in.
Well, I could do so easily, but wouldn't that be, and correct me if I am wrong, just global exposure of a local context? btw problem is solved via WM_KEYBOARD_LL as suggested by codeplug. Since I have no interest in repeat rate and usage of hotkeys that I am after is quite rare, I think I've found optimal and fast solution. Thank you all!
xlines is offline   Reply With Quote
Old 02-09-2010, 07:41 PM   #10
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,814
Quote:
Well, I could do so easily, but wouldn't that be, and correct me if I am wrong, just global exposure of a local context?
Does not shared memory imply the same?
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 02-09-2010, 09:06 PM   #11
Registered User
 
Join Date: Jan 2010
Posts: 230
If you expose the variable via an exported function, wouldn't that give every process that loads the dll their own copy the variable?
Where as if you use shared memory all processes share the same variable.
_Mike is offline   Reply With Quote
Old 02-09-2010, 11:56 PM   #12
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,814
If the variable lives in the CRT of the DLL this does not mean that other modules cannot see the value of the variable. It does not mean they can alter the value either unless of course you make a function to do so in the interface of the DLL. Is it a copy of the variable in the strictest sense of the word...not really. You could change the value of the returned variable and it would not affect the variable's value in the DLL as long as you do not return a reference or pointer to it. And my point is if the variable is global in the DLL then why is it and why does it need to be global in the DLL when other modules need it? The fact that the DLL has a global variable that other modules need throws up an immediate red flag for me.

Now if you pass a pointer from the DLL to another module then yes I would say that is a copy because it points to an address in the DLL's heap. If the DLL allocated the memory for the object then the DLL must cleanup the memory for the object. If other modules attempt to cleanup a pointer to memory in the DLL in the context of their own CRT they will corrupt their heap. This problem can be solved by using ref counted pointers or smart pointers. As long as the smart pointer cleans up inside the DLL then everything will work just fine.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 02-10-2010, 07:33 AM   #13
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,900
>> Why can't you just expose the global variable via a C or C++ function in the DLL?
>> Does not shared memory imply the same?
No. An exposed function in a DLL would only be called by code within the same process. Code in process A can not call a function of, or reference memory in, a DLL in process B. At least not without some kind of inter-process marshaling like COM does. I believe you already know this...

When process A calls SetWindowsHookEx(), certain hooks cause the system to inject your DLL into other processes. So you end up with your DLL being loaded by multiple processes - each DLL in their own address space with a distinct copy of all the DLL's data.

If the host process DLL has data needed by all the other instances loaded in other processes (or vice versa), then shared memory is a way to give all the instances a reference to common data.

WH_KEYBOARD_LL does not cause injection into other processes. You don't even need a DLL to use it. It's just a normal in-process callback - avoiding any need for shared memory.

gg
Codeplug is offline   Reply With Quote
Old 02-10-2010, 10:35 AM   #14
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,814
Maybe I'm missing something here or missed it in my original reading of the post. I thought that both were in the same process and the dialog box depended on a variable that was stored in the DLL. That would be simple. If this is an inter-process issue then my solution certainly would not work. My solution was assuming the DLL and the calling code were in the same process. That is why I was so confused as to why this was an issue.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Reply

Tags
dll, global value, sendmessage

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
DLL Global Object Constructor String Error n00b3 Windows Programming 1 06-29-2008 07:42 PM
global and static variable in a class delivered in a DLL George2 C++ Programming 16 04-13-2008 08:19 AM
dll communicating between each other cloudy C++ Programming 5 06-17-2005 02:20 AM
DLL: what's the difference between static and non static global variables? dit6a9 Windows Programming 2 10-02-2004 10:12 AM
global dll file The15th C++ Programming 3 09-05-2001 04:47 PM


All times are GMT -6. The time now is 08:03 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22