与 DLL 不工作的共享全局变量

Shared global variable with DLL not working

我正在尝试让一些在 Mac 上运行的代码在 Windows 上运行。该代码涉及在 DLL、静态库和主程序之间共享数据。我怀疑问题的出现是因为 Unix 和 Windows 处理全局变量的方式不同(例如,参见 the answers here)。但是,我还没有想出如何解决它。这是一个最小的例子:

我的 Visual Studio 2019 解决方案包含三个项目。

项目1制作静态库MarinaLib.lib

Header 是 MarinaLib.h

    #pragma once
    #include "Marina.h"

Class header 是 Marina.h

#pragma once

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

protected:
    static Marina* marina_instance;
};

源文件是Marina.cpp

#include "Marina.h"

Marina* Marina::marina_instance { nullptr };

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

项目 2 生成 DLL MarinaDLL.dll。它 #defines MARINADLL_EXPORTS

第一个源文件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 文件 MarinaDLL.h 是

#pragma once

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

QUERY_DECLSPEC void query_marina();

第二个源文件是marinaDLL.cpp

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

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

项目 3 生成可执行文件 MarinaExample.exe 而不是 #define MARINADLL_EXPORTS。它链接 MarinaLib.lib 和 MarinaDLL.lib

源文件MarinaExample.cpp是

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

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

第一行main(),代码输入Marina::get_marina()marina_instancenullptr 所以代码创建了一个新的 Marina 并使 marina_instance 指向它。这很好。

main() 的第二行,代码输入 query_marina() 并从那里进入 Marina::get_marina()。此时 marina_instancenullptr 这不是我想要的。我希望它保持以前的 non-null 值。

我在类似代码中看到了一些解决问题的示例,但它们似乎不适用于我的情况。关于如何解决这个问题有什么建议吗?

谢谢。

将导出修饰符添加到 class 定义并导出整个 class。

在 dll 和 lib 构建中定义 QUERY_DECLSPEC=export ,在 exe 构建中定义为 import :

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

protected:
    static Marina* marina_instance;
};