4

我有一个包含 3 个项目的解决方案:

  • Lib1(一个静态库)
  • Dll1(一个动态库)
  • App1(一个空白的 Windows Store 应用程序,可以是任何应用程序类型)

Lib1 包含以下内容:

导出.h

#pragma once

#ifdef DLL_EXPORT
    #define EXPORT __declspec(dllexport)
#else
    #define EXPORT __declspec(dllimport)
#endif

库1.h

#pragma once
#include "Export.h"

class Member { };

class EXPORT Base {
public:
    static Member* GetStaticMember();
    virtual void SetMember(Member* member) = 0;

protected:
    static Member* m_member;
};

class Worker {
public:
    void DoSomething();
};

库1.cpp

#include "pch.h"
#include "Lib1.h"

Member* Base::m_member;

Member* Base::GetStaticMember() {
    return m_member;
}

void Worker::DoSomething() {
    Member* test = Base::GetStaticMember(); // RETURNS 0
}

dll1包含以下内容

DLL1.h

#pragma once
#include "Lib1.h"
#include "Export.h"

class EXPORT ChildA : public Base {
public:
    virtual void SetMember(Member* member) override;
};

dll1.cpp

#include "pch.h"
#include "Dll1.h"

void ChildA::SetMember(Member* member) {
    Base::m_member = member;

    Member* test = Base::GetStaticMember(); // RETURNS CORRECT ADDRESS
}

App1 包含以下内容

Member* member = new Member();
ChildA* childa = new ChildA();
childa->SetMember(member); // Base::GetStaticMember() inside this RETURNS CORRECT ADDRESS

Worker* worker = new Worker();
worker->DoSomething(); // Base::GetStaticMember() inside this RETURNS 0

问题

在调试器中单步执行时,Base::GetStaticMember() 在设置成员后将正确的地址返回给成员(但仍在 childa->SetMember() 内部。一旦 OUTSIDE childa,Base::GetStaticMember() 改为返回 0。当在 worker->DoSomething() 内部时,Base::GetStaticMember() 也返回 0。谁能向我解释这是什么原因以及如何解决它,以便在外部或内部方法访问 Base::GetStaticMember() Dll 或 Lib 会返回正确的地址而不是 0?

4

2 回答 2

3

如果您使用链接到多个 DLL 和/或您的 EXE 的静态库,则每个都将获得自己的静态成员变量。想想每一个的 *link 阶段如何发生的机制,你就会明白为什么。

可以将静态变量转换为引用由内存映射文件支持的共享内存的指针,但我警告您管理起来会很棘手。我通过使用类的名称+成员+pid作为映射名称来维护一个临时内存映射文件来完成它(注意:pid是为了允许多个进程运行而不会相互踩踏共享内存)。它的效果出奇的好。

于 2012-10-20T19:09:46.980 回答
1

您应该lib1只链接Dll1App1,而不是两者。

现在你已经在你的和中Base::_member定义Dll1App1

当您定义Base__dllexport/__dllimport时,它使用Dll1静态成员,但您没有声明Worker任何属性,并且它使用本地静态成员。

我假设,您应该指定属性并且Worker不链接App1Lib1

于 2012-10-20T19:13:59.550 回答