Hey guys
I'm making a program which gots some threads that should exchange data. However since the environment I am working in got some limitations I have run out of ideas of how to solve my problem.
Lets say we got a program consisting of 2 files, 1 exe and 1 dll. The exe file will load the dll before it starts up itself so first the dllmain is run and after that the exe will run.
The dll and the exe got 1 spare thread each and these two threads needs to communicate. What I need to do is that the exe file will detect there is already a thread opened (from the dll) and recieve 32 bit data (a memory poiner) which only the dll knows about.
This problem boiles down to:
1. 2 threads finds each other
2. exchange of data
I thought of using named mutexes because they would allow me to have a mutex which I could query for. This could work by creating a named mutex in both exe and dll and on the 2nd creating it would fail by saying it's already existing which is solving the first part of the problem. But this won't allow me to exchange data.
Another way would be using a file. Thread 1 would create the file and save the data needed. Thread 2 already knows the filename so it will attempt to open this file and read it. But I don't want to have external devices involved because it's something that really belongs inside memory and not on HD.
Maybe someone knows if a mailslot can solve the situation?
The ideal situation would be to have a api which allows that you send a data value with it when you signal it's state.
Thanks in advance.
// CyberHeg
I'm making a program which gots some threads that should exchange data. However since the environment I am working in got some limitations I have run out of ideas of how to solve my problem.
Lets say we got a program consisting of 2 files, 1 exe and 1 dll. The exe file will load the dll before it starts up itself so first the dllmain is run and after that the exe will run.
The dll and the exe got 1 spare thread each and these two threads needs to communicate. What I need to do is that the exe file will detect there is already a thread opened (from the dll) and recieve 32 bit data (a memory poiner) which only the dll knows about.
This problem boiles down to:
1. 2 threads finds each other
2. exchange of data
I thought of using named mutexes because they would allow me to have a mutex which I could query for. This could work by creating a named mutex in both exe and dll and on the 2nd creating it would fail by saying it's already existing which is solving the first part of the problem. But this won't allow me to exchange data.
Another way would be using a file. Thread 1 would create the file and save the data needed. Thread 2 already knows the filename so it will attempt to open this file and read it. But I don't want to have external devices involved because it's something that really belongs inside memory and not on HD.
Maybe someone knows if a mailslot can solve the situation?
The ideal situation would be to have a api which allows that you send a data value with it when you signal it's state.
Thanks in advance.
// CyberHeg
You can register a custom window message or use a memory mapped file as a FIFO.
Why a memory mapped file? The two threads are associated with the same process, and therefore the same context anyway.
Erm, how about just having a function in the DLL that returns the handle of
the thread it has started, and post messages to this thread.
Erm, how about just having a function in the DLL that returns the handle of
the thread it has started, and post messages to this thread.
Might WM_COPYDATA not work? The COPYDATASTRUCT structure is designed to pass data to another application and should work between exe and dll without problem. The mutex is a good idea to establish communication, but you might also be able to use an event, Create it in the exe and Open it in the dll where you want to signal the exe (you can use this to wait until the dll is fully loaded for example before resuming exe execution)
Kayaker
invoke CreateEventA, 0, 0, 0, ADDR EventName
mov hCreateEvent, eax
invoke WaitForSingleObject, hCreateEvent, 100000
...and in another thread far far away...
;-------------------
; Signal Event
;-------------------
invoke OpenEventA, EVENT_MODIFY_STATE, 0, ADDR EventName
push eax
invoke SetEvent, eax
pop eax
invoke CloseHandle, eax
Kayaker
Would it be possible to make window messages without actually showing anything on screen?
About having a function in the DLL that returns the handle of the thread it has started it would require that the exe file knows the name of the dll which might not always be possible in my case. The program should be dynamic in such a way so two threads should still be able to communicate even if you replace one dll with another or two dll's exist.
// CyberHeg
About having a function in the DLL that returns the handle of the thread it has started it would require that the exe file knows the name of the dll which might not always be possible in my case. The program should be dynamic in such a way so two threads should still be able to communicate even if you replace one dll with another or two dll's exist.
// CyberHeg
But the program has to have the DLL's name stored somewhere, how else is it going to load it?
If you meant that another program loads the DLL, then the situation is different. You should then use CreateFileMapping to create a named shared memory block in both processes.
You can use the PostThreadMessage function to post messages to a thread that doesn't have a window. But the thread has to have a message queue.
If you meant that another program loads the DLL, then the situation is different. You should then use CreateFileMapping to create a named shared memory block in both processes.
You can use the PostThreadMessage function to post messages to a thread that doesn't have a window. But the thread has to have a message queue.
I solved it now but in a completely other way then originally proposed.
Environment strings using _putenv() and _getenv() are specific to the current process so what I did was to run getenv() and see if I got a null pointer. If this is the case then I would make the data to be shared with sprintf like "var=data" and save it using _putenv(). The next dll will then run getenv() and will get a pointer which is not NULL and from there I can get the data out by using sscanf().
This gives flexibility because I can run an unlimited number of sub dll's without worrying about how many there are or their names. The only thing they need to know is the environment variable name.
// CyberHeg
Environment strings using _putenv() and _getenv() are specific to the current process so what I did was to run getenv() and see if I got a null pointer. If this is the case then I would make the data to be shared with sprintf like "var=data" and save it using _putenv(). The next dll will then run getenv() and will get a pointer which is not NULL and from there I can get the data out by using sscanf().
This gives flexibility because I can run an unlimited number of sub dll's without worrying about how many there are or their names. The only thing they need to know is the environment variable name.
// CyberHeg
Mutex == bad, as they won't be cleaned if process terminates abruptly.
environment vars? Well, why not. I'd probably have gone for a Memory Mapped File (backed by swap, ie not creating a "real" file on disk) or named pipes (if I don't care about 9x). I still need to have a look at mailslots and other IPC methods.
environment vars? Well, why not. I'd probably have gone for a Memory Mapped File (backed by swap, ie not creating a "real" file on disk) or named pipes (if I don't care about 9x). I still need to have a look at mailslots and other IPC methods.
I still don't see how you can load the DLLs without knowing their names. I take it that you have a setup program which patches the import section with some DLL names. In this case, you could have the main program export a function for communicating with it. The DLLs could then retrieve the address of that function when starting up. That is much simpler.
I still don't see how you can load the DLLs without knowing their names. I take it that you have a setup program which patches the import section with some DLL names. In this case, you could have the main program export a function for communicating with it. The DLLs could then retrieve the address of that function when starting up. That is much simpler.
There is a reason for everything...
The thing I'm developing is a library which other developments can link their code against. What I need is one shared global variable among all exe and dll's in the running process. The names of the dll's aren't unknown. They are defined by the users of this library. However they are not known to me. This is why I could not rely on filenames and only on other data which can be used as a identifier (in this case a variable name). Using exported functions could be a way but again since I don't know the filenames it's not easy for me to deal with that.
// CyberHeg
again, mutex == bad.
And rather than fisrt checking for mutex then env var, you can just check if env var exists.
And rather than fisrt checking for mutex then env var, you can just check if env var exists.
I really am sorry f0dder I skipped right over your post without seeing it. I have deleted mine.
don't delete posts donkey, others will see and learn from mistakes :)
:grin: That's not the reason I deleted it, It's because we said the same thing. The EnVar problem is about the same as the mutex, how do you know if it isn't supposed to be modified. If you delete it when the last thread is finished, well when you have a bad exit it won't be deleted and how is the software supposed to know. Just a thought about that.
Ah, I see, that explains it very well. Well, actually, the environment block is freed automatically by the system when the process ends, but I think you could do all this by having the main executable export the necessary data, and then the DLLs could get at it with GetModuleHandle(0) and then GetProcAddress, if I understood you correctly. What kind of library is this anyway?