0

I have two classes with the same name in different namespaces. I cannot modify the names of the classes. I want to add a method to one of the class, but I'm not allowed to add this as a public method. The other class is written in C++/CLI as ref class and needs access to this method. I tried to use friend class but I have no idea how I should use it.

dll in standard c++:

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

application in C++/CLI

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

I've tried the following: friend class Y::A; // compiler error C2653: Y is not a class or namespace name

when I declare the namespace Y I get the error C2039: 'A' : is not a member of 'Y'

I cannot add a forward declaration of class A in namespace Y because class A is compiled with standard C++ and in a forward declaration I have to declare it as ref class.

Compiler: Visual Studio 2008

Does anybody have an idea?

Thank you

Solution (thanks to 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();
    }
}
user37337
  • 317
  • 2
  • 18

1 Answers1

1

I'm not sure if this kind of trick is allowed.

but maybe you would like to have a look on this kind of "hacking":

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

edit:

I have tested that this could pass the compiling

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

maybe you just need to copy the header file of X::A and edit the copy by adding a declare (not define) Y::A before namespace X. and include the "copy" instead.

Sorayuki
  • 256
  • 2
  • 7
  • I think this works but this is not a nice piece of code. I have to use this kind of hack if there is no different way but I don't know whether I'm allowed to use it. – user37337 Apr 24 '13 at 09:16
  • Thank you but this does not compile with a standard C++ compiler. The dll does not use .NET. I've talked to my customer: I can use your first answer. – user37337 Apr 24 '13 at 11:19
  • I know. So I suggest you to make a copy of that .h then modify it, or that dll will not compile. By the way, you may define a macro MYREF or something, when compiled with other compiler it's defined as nothing and when compiled with .net it's defined as "ref". – Sorayuki Apr 24 '13 at 11:22