0

異なる名前空間に同じ名前の 2 つのクラスがあります。クラスの名前を変更できません。クラスの 1 つにメソッドを追加したいのですが、これを public メソッドとして追加することは許可されていません。もう 1 つのクラスは C++/CLI で ref クラスとして記述されており、このメソッドにアクセスする必要があります。フレンド クラスを使用しようとしましたが、どのように使用すればよいかわかりません。

標準の c++ の dll:

namespace X
{
    class A
    {
        protected:
        __declspec(dllexport) void method();
    }
}

C++/CLI でのアプリケーション

namespace Y
{
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            otherClass.method();
        }
    }
}

私は次のことを試しました: フレンド クラス Y::A; // コンパイラ エラー C2653: Y はクラスまたは名前空間の名前ではありません

名前空間 Y を宣言すると、エラー C2039: 'A' : is not a member of 'Y' が表示されます

クラス A は標準 C++ でコンパイルされており、前方宣言では ref クラスとして宣言する必要があるため、名前空間 Y にクラス A の前方宣言を追加できません。

コンパイラ: Visual Studio 2008

誰かアイデアがありますか?

ありがとうございました

解決策 (Sorayuki さんに感謝):

#ifdef __cplusplus_cli
    #define CLI_REF_CLASS ref class
#else
    #define CLI_REF_CLASS class
#endif

namespace Y { CLI_REF_CLASS A; }

namespace X
{
    class A
    {
        protected:
        friend CLI_REF_CLASS Y::A;
        __declspec(dllexport) void method();
    }
}
4

1 に答える 1

1

この種のトリックが許されるかどうかはわかりません。

しかし、この種の「ハッキング」を見てみたいと思うかもしれません:

C++/cli で

namespace Y
{
    class HackA : public X::A {
        public:
        void CallMethod() { method(); }
    };
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            assert(sizeof(HackA) == (X::A));
            HackA* p = (HackA*) &otherClass;
            p->CallMethod();
        }
    };
};

編集:

これがコンパイルに合格することをテストしました

namespace Y { ref class A; };

namespace X
{
    class A
    {
        friend ref class Y::A;
        protected:
        __declspec(dllexport) void method();
    };
};

namespace Y
{
    ref class A
    {
        void someMethod()
        {
            X::A otherClass;
            otherClass.method();
        }
    };
};

おそらく、X::A のヘッダー ファイルをコピーし、名前空間 X の前に Y::A の宣言 (定義ではない) を追加してコピーを編集し、代わりに「コピー」を含める必要があるだけです。

于 2013-04-24T08:50:17.577 に答える