开发者

How can I coordinate various DLLs in the same process, without help from the host program?

开发者 https://www.devze.com 2023-03-30 18:18 出处:网络
I am looking for a way to coordinate DLLs in the same process, in order to provide a data sharing mechanism between them. The goal is to have the same sharing code for all DLLs, and to h开发者_开发知识

I am looking for a way to coordinate DLLs in the same process, in order to provide a data sharing mechanism between them. The goal is to have the same sharing code for all DLLs, and to h开发者_开发知识库ave them coordinate in such a way that the first one loaded by the main program will act as the manager for shared items, while the others will use this manager. I cannot modify the main application, so having that set up the manager and sharing its memory address with the other DLLs is not possible. The set of DLLs using this mechanism can vary, so I cannot assume explicitly that one of them will be loaded.

One solution I considered is to add the memory address to the environment variables of the process. The first DLL would see that the environment variable is not set yet, create the manager object and set the variable to its address. The other DLLs would see the variable and create a pointer to the manager object from that.

This comes close to what I want, but it seems a bit crude, since there is no guarantee that the environment variable isn't set already for some reason, and SetEnvironmentVariable/GetEnvironmentVariable can fail for various reasons.

Is there a better way to handle this? I'm looking for a way to store and retreive a named pointer in the context of a process, but if you have a better solution for the underlying problem of getting the DLLs to cooperate I'd be happy to accept this as well.


how about creating a named shared memory ?

that would allow you to share a part of memory, without the hassle of obtaining an address valid in the process context. the first DLL loaded creates the shared memory, the next DLL can then directly access the memory, you can build your own messaging API on top of this.


Combine GetModuleHandle() with GetProcAddress() to achieve this. The dependent DLLs will obtain the handle to the manager DLL, and then use GetProcAddress() to retrieve pointers from the symbols that it exports.

Or just dynamically link the dependent DLLs against the manager DLLs and use a header file for the extern definitions.


I misread your question initially; however, the above approach can still be useful.

You can require that these DLLs all export an identical symbol that will point to some structure or function. Then, when one of the libraries is initialized, it can enumerate the loaded modules in the process and look for that symbol. If dereferencing the pointer returned by GetProcAddress() returns a null pointer, then this module is the first one loaded and should create the required structure and set its own variable. Otherwise, it uses the value obtained from the pointer.

This method is fraught with race-conditions though, if these modules can be initialized concurrently. You would be better off having a single supervisor module that each module can use as a communication point.


cdhowie provides some good reasons why this is a bad idea.

However, if you really want to do this, without polluting the global shared memory namespace: Register a window class in your DLL entry point, but pass the EXE's instance as the hInstance field of the window class.

Each DLL can check if the class is already registered; if not, register itself. The first DLL to successfully register the window class becomes the master. To obtain a pointer to some structure initialized by the master in the subsequently loaded DLLs, then, create a message-only window of that class, and use SendMessage to invoke its window procedure (in the master DLL).

0

精彩评论

暂无评论...
验证码 换一张
取 消