3

I'm working on a project in MSVC++ 2012, and I'm trying to split it up into smaller parts. Currently, the dependencies looks something like this:

output.exe --- deploy.dll --- coreext.dll
                          |
                          |-- physical.dll --- coreext.dll
                          |
                          |-- renderer.dll --- physical.dll --- coreext.dll
                          |                |
                          |                |-- coreext.dll
                          |
                          |-- engine.dll ----- physical.dll --- coreext.dll
                                           |
                                           |-- coreext.dll

I have a bit of global data that gets changed in "physical.dll" but it seems that this change doesn't apply to all instances of physical.dll. The value changes at the "deploy.dll" level, but not at the "engine.dll" level. Currently, I'm using implicit linking. There are three more layers of dependencies in the actual output, but I'm just working on these parts here for now.

For the life of me, I cannot seem to figure out how to pass the data around to the proper level either. I put a function in renderer.dll and engine.dll to set the global data, but when going line-by-line with the debugger, it isn't a valid pointer once it goes in - probably some virtual address thing?

I saw this, which gave me the impression this shouldn't be an issue. Then this lead me to this, which I'm reading and trying to wrap my head around it. This is my first time doing this in Windows, and I get the feeling that I'm approaching this sort of design all wrong.

I don't want to do a large load of dumpbin and GetProcAddress()'s as there's thousands of functions to go through, and that would be a pain to maintain (but still automatable I suppose) and the code is nowhere as clean. Besides changing all my DLLs to a collection of OBJ files and linking those - which works, but puts me back where I was - how can I get this working?

Community
  • 1
  • 1
Jay
  • 31
  • 1
  • 3
  • There is only one instance of any DLL in a process. – user253751 Mar 15 '15 at 22:49
  • That's what I thought, but the data changing when it jumps from DLL to DLL in the step-by-step debug is telling me otherwise. How could I be screwing this up? – Jay Mar 15 '15 at 22:52
  • 2
    Are you sure you don't have multiple copies of the *variable* by mistake - like one in each DLL? (which might happen if you forget to use dllimport/dllexport) – user253751 Mar 15 '15 at 22:53
  • That could be it. Right now I have it as a private static variable inside of a class to store an instance, and a public static function to retrieve that instance. I was having some massive linker problems exporting the variable itself, but I'll give that a shot again. – Jay Mar 15 '15 at 22:55

1 Answers1

1

Only processes and threads of a programme have their own life and data.

DLL are just a technical mean to put some identical definitions in a distinct file instead of putting them as usual in the executable. So they don't have their own data. By the way, while there could be several instance of your programme loaded (each having its own independent state and global variables), only one DLL can be loaded once.

In consequence what you show is not multiple instances of the DLL, but multiple dependencies to the same DLL (unless you have DLLs in different versions).

The DLLs content, code and data, is mapped into the address space of the calling process. So a global variable in a DLL are indeed global variables of your programme. The DLL cannot have its own. Eventually, sharing of data between processes using the same DLL is possible but requires creating a shared data segment as explained in this MSDN article.

What is however probable, llooking at your symptoms, is that you define several times a global data (examples : static definitions in a header, or global definitions in a header using an anonymous namespace). In this case, you would think that you always refer to the same global variable, but each .obj, and each .dll would use its own copy.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • That makes sense. How would I make the separate pieces refer to the same static variable? I've double checked my dllexport/dllimport on the variable. Instantiating inside of physical.dll shouldn't matter if it's dllexport on the variable for building physical.dll and dllimport on the variable for building engine.dll, correct? – Jay Mar 16 '15 at 01:06
  • 1
    Seems correct indeed. But is it static class member or static global ? Could you show how it's declared in the headers and how it's instanciated (including namespace context if any) ? – Christophe Mar 16 '15 at 07:10