4

私は3つのプロジェクトで設定されたソリューションを持っています:

  • Lib1 (静的ライブラリ)
  • Dll1 (動的ライブラリ)
  • App1 (空白の Windows ストア アプリケーション、任意のアプリケーション タイプである可能性があります)

Lib1 には以下が含まれます。

エクスポート.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() はメンバーが設定された後に正しいアドレスを返します (ただし、childa->SetMember() の内部ではまだです)。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 に答える