Thread: C++ / CLI forward declaration problem

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    C++ / CLI forward declaration problem

    Given this example:

    Interface dll header
    Code:
    namespace Foo
    {
       ref struct SomeStruct;
    
       public interface class ISomeInterface
       {
           SomeStruct ^ GetStruct();
       }
    }
    Interface dll cpp for type creation only
    Code:
    #include "ISomeInterface.h"
    Impl dll - has a reference to interface dll in the project
    Code:
    namespace Foo
    {
       struct SomeStruct
       {
           int someValue;
       };       
    
        public ref class InterfaceImpl : ISomeInterface
        {
             SomeStruct ^ GetStruct()
             {
                   return gcnew SomeStruct();
             }
        }
    }
    This code does not compile. The compiler complains that GetStruct() return type does not match that of the interface return type. This in turn causes the compiler to yell about InterfaceImpl not implementing ISomeInterface.

    This seems to only happen on forward declarations that are used as managed pointers. Why does the compiler say that InterfaceImpl::GetStruct() is not the implementation of ISomeInterface::GetStruct()?

    Two things I notice:
    • SomeStruct is not visible in ISomeInterface.dll in the object browser
    • Since SomeStruct is a simple forward declaration to make the compiler happy and the type obviously is not created as evidenced by the above bullet point...how then is it complaining that the signature of the impl does not match the signature of the interface?
    Last edited by VirtualAce; 08-19-2011 at 04:57 PM.

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    From the doc page of that compiler error:
    Quote Originally Posted by C4488
    A class must implement all members of an interface from which it directly inherits. An implemented member must have public accessibility, and must be marked virtual.
    Code:
    public ref class InterfaceImpl : ISomeInterface
    {
    public:
        virtual SomeStruct^ GetStruct()
        {
           return gcnew SomeStruct();
        }
    };
    Also you're missing the 'ref' off the definition of SomeStruct

    Code:
    #include "ISomeInterface.h"
    
    namespace Foo
    {
       ref struct SomeStruct
       {
           int someValue;
       };
    
        public ref class InterfaceImpl : ISomeInterface
        {
        public:
            virtual SomeStruct^ GetStruct()
            {
               return gcnew SomeStruct();
            }
        };
    }
    
    int main()
    {
        Foo::InterfaceImpl^ pImp = gcnew Foo::InterfaceImpl();
        Foo::SomeStruct^ pStruct = pImp->GetStruct();
        Console::WriteLine("pStruct->someValue = {0}", pStruct->someValue);
    }
    Compiles and runs for me, with a warning that the definition of SomeStruct has only internal visibility. If you want any code from ISomeInterface.cpp or any module other than the one the definition is in to be able to reference it, you'll have to make it public.
    Last edited by adeyblue; 08-19-2011 at 06:21 PM.

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    My posted example was off a bit but in my code all that you said was missing is there. I get error C2553: overriding virtual function return type differs from 'blah blah'. The compiler will not allow public nor any access modifier on a forward declaration in the interface header so I cannot put public in the forward declaration. When I define it using public as the access modifier in the impl header all is well until I try to use it as a managed pointer return type and then the compiler does not see that the forward declaration is implemented in my impl header and thus it also does not see that the return type is identical to the interface.

    If I remove public from the definition in the impl header I will get warning C4677 which is essentially telling me what you said. Regardless of that fact I still get error C2553 later on and thus it does not compile. I have tested this so far on MSVS 2005 and MSVS 2008 and neither of them compile.

    When compiling the interface I get linker error LNK4248 complaining about an unresolved token which could cause the assembly not to run. This is fine b/c this DLL is simply acting as an interface.
    Last edited by VirtualAce; 08-19-2011 at 07:36 PM.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well to complete this thread I did resolve the issue but I could not use the forward declare. I was forced to move all the struct impls to the interface DLL as well as make some of the accessors and mutators into properties in order to get the thing to compile. I still do not understand why forward declaration does not work but at least I did get past this. As of COB today I had most everything working as expected with a few minor hitches. After reading my C++/CLI book I still cannot figure out why the forward declaration signature did not match the impl signature.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Forward declaration with g++
    By blakaxe in forum C++ Programming
    Replies: 4
    Last Post: 06-17-2009, 11:44 AM
  2. Forward declaration with g++
    By blakaxe in forum Linux Programming
    Replies: 0
    Last Post: 06-15-2009, 09:22 AM
  3. forward declaration
    By steve1_rm in forum C Programming
    Replies: 5
    Last Post: 01-29-2009, 07:13 PM
  4. yet another forward declaration problem.
    By sloppy_coder in forum C++ Programming
    Replies: 2
    Last Post: 12-12-2005, 02:59 AM
  5. Forward Declaration
    By BigDaddyDrew in forum C++ Programming
    Replies: 4
    Last Post: 02-01-2003, 12:15 PM