如何在不需要主机程序帮助的情况下在相同的进程中协调各种DLL?

我正在寻找一种方法来在同一个进程中协调DLL,以提供它们之间的数据共享机制。 目标是为所有DLL提供相同的共享代码,并让它们以这样一种方式进行协调,即主程序加载的第一个代码将用作共享项目的pipe理器,而其他代码将使用此pipe理器。 我不能修改主应用程序,所以设置pipe理器并与其他DLL共享内存地址是不可能的。 使用这种机制的DLL集可以改变,所以我不能明确地假设其中的一个将被加载。

我考虑的一个解决scheme是将内存地址添加到进程的环境variables中。 第一个DLL会看到环境variables尚未设置,创buildpipe理器对象并将该variables设置为其地址。 其他的DLL会看到这个variables,并从中创build一个指向pipe理器对象的指针。

这接近我想要的,但似乎有点粗糙,因为不能保证环境variables没有被设置已经出于某种原因,SetEnvironmentVariable / GetEnvironmentVariable可以由于各种原因失败。

有没有更好的方法来处理这个问题? 我正在寻找一种方法来存储和检索一个进程的上下文中的指定指针,但是如果你有一个更好的解决scheme来获得DLL的合作的基本问题,我很乐意接受这一点。

结合GetmoduleeHandle()GetProcAddress()来实现这一点。 依赖DLL将获得管理器DLL的句柄,然后使用GetProcAddress()从其导出的符号检索指针。

或者只是动态链接依赖的DLL对管理器的DLL,并使用头文件的外部定义。


我最初误解了你的问题; 但是,上述方法仍然有用。

您可以要求这些DLL都导出一个指向某个结构或函数的相同符号。 然后,当其中一个库被初始化时,它可以枚举进程中的加载模块并查找该符号。 如果取消引用由GetProcAddress()返回的指针返回一个空指针,那么这个模块是第一个加载的,应该创建所需的结构并设置自己的变量。 否则,它使用从指针获得的值。

如果这些模块可以同时初始化,这种方法充满了竞争条件。 你最好有一个单独的管理模块,每个模块可以用作通信点。

如何创建一个命名的共享内存 ?

这将允许您共享内存的一部分,而没有在过程上下文中获取有效的地址的麻烦。 第一个加载的DLL创建共享内存,下一个DLL可以直接访问内存,您可以在此之上构建自己的消息传递API。

cdhowie提供了一些很好的理由,为什么这是一个坏主意。

但是,如果你真的想要这样做,而不污染全局共享内存命名空间:在DLL入口点注册一个窗口类,但传递EXE的实例作为窗口类的hInstance字段。

每个DLL可以检查该类是否已经注册; 如果不是,则自行注册。 成功注册窗口类的第一个DLL成为主窗口。 要获得指向由后续加载的DLL中的master初始化的某个结构的指针,请创建该类的仅消息窗口,并使用SendMessage调用其窗口过程(在主DLL中)。