Search code examples
c++windowsdllglobal-variables

Shared global variable with DLL not working


I'm trying to get some code that works on the Mac to work on Windows. The code involves sharing data between a DLL, a static library and the main program. I suspect the problem arises because of the differences in the way that Unix and Windows handle global variables (see, for example, the answers here). However, I haven't figured out how to fix it. Here's a minimal example:

My Visual Studio 2019 solution contains three projects.

Project 1 makes the static library MarinaLib.lib

Header is MarinaLib.h

    #pragma once
    #include "Marina.h"

Class header is Marina.h

#pragma once

class Marina
{
public:
    static Marina* get_marina();

protected:
    static Marina* marina_instance;
};

Source file is Marina.cpp

#include "Marina.h"

Marina* Marina::marina_instance { nullptr };

Marina* Marina::get_marina()
{
   if( !marina_instance )
      marina_instance = new Marina();
   return marina_instance;
}

Project 2 makes the DLL MarinaDLL.dll . It #defines MARINADLL_EXPORTS

First source file dllmain.cpp

// dllmain.cpp : Defines the entry point for the DLL application.
#include "framework.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Header file MarinaDLL.h is

#pragma once

#ifdef MARINADLL_EXPORTS
#define QUERY_DECLSPEC __declspec(dllexport)
#else
#define QUERY_DECLSPEC __declspec(dllimport)
#endif

QUERY_DECLSPEC void query_marina();

Second source file is marinaDLL.cpp

#include "MarinaDLL.h"
#include "..\MarinaLib\Marina.h"

void query_marina()
{
   auto inst = Marina::get_marina();
}

Project 3 makes the executable MarinaExample.exe and does not #define MARINADLL_EXPORTS. It links in MarinaLib.lib and MarinaDLL.lib

The source file MarinaExample.cpp is

#include "MarinaLib.h"
#include "MarinaDLL.h"

int main()
{
   auto instance = Marina::get_marina();
   query_marina();
}

In the first line of main(), the code enters Marina::get_marina(). marina_instance is nullptr so the code creates a new Marina and makes marina_instance point to it. This is fine.

In the second line of main(), the code enters query_marina() and from there goes into Marina::get_marina(). At this point marina_instance is nullptr which is not what I want. I would like it to maintain its previous non-null value.

I've seen some examples of solutions to problems in similar code but they don't seem to work in my situation. Any suggestions on how to fix this?

Thanks.


Solution

  • add export modifier to class definition and export the whole class.

    In dll and lib build define QUERY_DECLSPEC=export , in exe build as import :

    class QUERY_DECLSPEC Marina
    {
    public:
        static Marina* get_marina();
    
    protected:
        static Marina* marina_instance;
    };