在Static Lib和DLL中使用静态成员 - 成员值正在重置

时间:2012-10-20 18:48:49

标签: c++ dll static-libraries static-members dllexport

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

  • Lib1(静态库)
  • Dll1(动态库)
  • App1(空白Windows应用商店应用,可以是任何应用类型)

Lib1包含以下内容:

Export.h

#pragma once

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

Lib1.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();
};

Lib1.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()会在成员设置后返回正确的地址(但仍然在child-> SetMember()内。一旦OUTSIDE childa,Base :: GetStaticMember()改为0。当在worker-> DoSomething()中时,Base :: GetStaticMember()也返回0.任何人都可以向我解释这是什么原因以及如何修复它以便访问Base :: GetStaticMember()在Dll或Lib的外部或内部方法将返回正确的地址而不是0?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

您应该lib1仅与Dll1App1相关联,而不是两者。

现在,您Base::_memberDll1App1定义了

在您定义Base__dllexport / __dllimport时,它会使用Dll1静态成员,但您没有使用任何属性声明Worker,它使用 local 静态成员。

我认为,您应指定Worker的属性,不要将App1Lib1

相关联