我有一个包含3个项目的解决方案:
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.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
}
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?
答案 0 :(得分:2)
如果您正在使用链接到多个DLL和/或EXE的静态库,则每个都将获得其自己的静态成员变量。想想每种情况的*链接阶段如何发生的机制,你会明白为什么。
您可以将静态变量转换为引用内存映射文件支持的共享内存的指针,但我警告您管理起来很棘手。我通过使用类+ member + pid的名称作为映射名称来维护临时内存映射文件来完成它(注意:pid是允许多个进程运行而不会踩到彼此的共享内存)。它的效果令人惊讶。
答案 1 :(得分:0)
您应该lib1
仅与Dll1
或App1
相关联,而不是两者。
现在,您Base::_member
和Dll1
已App1
定义了 。
在您定义Base
班__dllexport
/ __dllimport
时,它会使用Dll1
静态成员,但您没有使用任何属性声明Worker
,它使用 local 静态成员。
我认为,您应指定Worker
的属性,不要将App1
与Lib1