2
votes

I have a DLL that will be loaded by a program, and that DLL will in turn load another DLL to handle some stuff that ought not to be in the main DLL. However, the second DLL needs to be able to talk to the first DLL. Is it possible for a DLL to use exported functions in the DLL that loaded it? For instance

  1. Program loads DLL A with LoadLibrary.
  2. DLL A loads DLL B with LoadLibrary.
  3. DLL A calls some functions in DLL B with GetProcAddress.
  4. B in turn does GetProcAddress on DLL A and calls some functions.
  5. DLL A is hobnobbing with the main program as DLL B is doing things and calling DLL A's exported functions.

Will this work, and is it the proper way to do it?

3
It's possible, but why don't you use a callback instead? - ruslik
How? I've never used a callback in C++, and don't know how. - SamJam
Another alternative: DLL A gives DLL B the pointers that it needs, up front. That means that DLL B needs to export a function void Import(function1fromA, function2fromA, function3fromA) which will be called by DLL A. - MSalters

3 Answers

5
votes

Yes, it will work. DLL B can safely call LoadLibrary on DLL A to get the instance handle for the GetProcAddress call the function it needs. The module loader will figure out that DLL A is already in the process memory and will just return an instance handle for it to DLL B.

Note: there are specific caveats with versioning though, when the main program depends and loads one version of the DLL A, and DLL B needs a different version. If that is the case, DLL B has to call LoadLibrary with explicit path to the version of DLL A it needs, and DLL A has to be SxS-enabled to support loading two versions of it in the process memory.

The easiest way to avoid this would if you control both the process and DLL B, to always ensure they need/use the same version of DLL A.

0
votes

Isn't it the exact task of Containers? and more to say that make your dependencies clear, extract the shared functionality and move it to another DLL, don't make a loop in dependencies graph

0
votes

Yes, it will work (I had a similar situation in a commercial product I worked on years ago). However, it IS a nightmare and a half. I would suggest modifying your library structure to avoid the circular dependency. Callbacks or creating another library to marshal between the other 2 both would work and will make your life much easier down the road. Versioning issues are just the tip of the iceberg; debugging issues in an architecture with a circular dependency can make your head spin.