none
Ref class vs. non ref class RRS feed

  • Question

  • This is probably a pretty common problem....but I'm in a pinch, and no time for research.

    I have a class that's not a ref class.  And the reason for that is that I am using a type from an old library that VSTO won't let me compile.
    Something like this:

    namespace SBITS {
        public class SmartBits {
            public: 
             SmartBits() {}
            private:
               HTStructure st;
        };
    }


    but when I try to instantiate this class from a ref class, it says that there is no such thing as SBITS, SmartBits, and sbits.

    public ref class RefClass {
        public:
           RefClass() {
                 sbits = gcnew SBITS::SmartBits();
            }
        private:
           SBITS::SmartBits ^sbits;
    };

    I have the Reference added correctly and everything, and if I change the SmartBits class to a ref type, I get error messages about the HTStructure type.

    Let me know if this doesn't make sense.

    Thanks



    Tuesday, December 12, 2006 1:27 AM

Answers

  • a non-ref class is a normal unmanaged C++ class so you need to treat it as such. In this case, SmartBits is fine, but the way you are using it in RefClass is wrong. Change it to this:

    public ref class RefClass {
        public:
           RefClass() {
                 sbits = new SBITS::SmartBits(); //not gcnew
            }
        private:
           gcroot<SBITS::SmartBits *> sbits; //not ^
    };

    So don't use gcnew when instantiating a normal C++ class.

    The gcroot<> template is required any time you want to have an umanaged member variable in a managed (ref) class.

    I hope that makes sense. But we still aren't finished.

    The error says it doesn't know anything about SBITS which probably means that you have missed adding the header file that contains SmartBits as a #include into the file that contains RefClass.

    The final problem might be if SmartBits is in a separate DLL from RefClass. In this case, you will need to export SmartBits out of the DLL using the non .NET method (__dllexport rather than just making it public).

     

    Hope that helps

    Jero

    Tuesday, December 12, 2006 3:02 AM

All replies

  • a non-ref class is a normal unmanaged C++ class so you need to treat it as such. In this case, SmartBits is fine, but the way you are using it in RefClass is wrong. Change it to this:

    public ref class RefClass {
        public:
           RefClass() {
                 sbits = new SBITS::SmartBits(); //not gcnew
            }
        private:
           gcroot<SBITS::SmartBits *> sbits; //not ^
    };

    So don't use gcnew when instantiating a normal C++ class.

    The gcroot<> template is required any time you want to have an umanaged member variable in a managed (ref) class.

    I hope that makes sense. But we still aren't finished.

    The error says it doesn't know anything about SBITS which probably means that you have missed adding the header file that contains SmartBits as a #include into the file that contains RefClass.

    The final problem might be if SmartBits is in a separate DLL from RefClass. In this case, you will need to export SmartBits out of the DLL using the non .NET method (__dllexport rather than just making it public).

     

    Hope that helps

    Jero

    Tuesday, December 12, 2006 3:02 AM
  • That is a great suggestion...and I got it to work like you suggested.
    But...
    If you don't want to gcroot<>, and you don't want to get yelled at for using native types in managed code...just don't use native types as members in the class.  Use functions that call the native types..

    //
    // DOESN"T PLAY WELL WITH OTHERS
    namespace SBITS {
        public class SmartBits {
            public: 
             SmartBits() {}
            private:
               HTStructure st;
        };
    }

    //
    // DOES PLAY WELL WITH OTHERS
    namespace SBITS {
        public ref class SmartBits {
           public: SmartBits() {}
                      unsigned long value;
           private:  System::Void GetSomething()
                         {
                             HTStructure st;
                             value = st.somevalue;
                          }
        };
    }


    I realize this won't be effective in certain situations (where you need to access the native type directly).
    Wednesday, December 13, 2006 2:18 AM