C++ CLI: cliext::vector as return type of publi

2019-08-10 21:29发布

问题:

I have next class in C++ CLI:

   public ref class MyClass
   {
        public:
           MyClass(void);
           virtual bool Init();

           cliext::vector<int>^ ListOfNumbers();
   };

I would like to recive vector of int from public fucntion.

Here is impl:

cliext::vector<int>^ MyClass::ListOfNumbers()
{
    cliext::vector<int>^ devs = gcnew cliext::vector<int>();
    devs->push_back(1);
    return devs;
}

My problem is that I got next warning:

warning C4677: 'ListOfNumbers': signature of non-private member contains assembly private type 'cliext::vector<_Value_t>'

Could someone tell me the reason? Could I receive collection of items from public function C++ CLI class?

回答1:

Actually, I don't know it, but I wouldn't be suprised if all CLI template instantiations were private and not exposable through the public assembly interface. You know, the template types generated by C++/CLI aren't really helpful when talking to other .Net assemblies, and "talking to other .Net" is just what C++/CLI is for.

"Native C++ templates" if (I can call them like that) are usable and accessible only from C++ side. CLR runtime cannot operate on them in general, as the C++ part of the compiler is not able to generate proper type description for these. (*)

For creating .Net interfaces, use .Net BCL types. Use generics instead of templates. So, look at types like System.Collections.Generic.List<>. They can safely be exposed in public interfaces. (**)

Remember that C++/CLI is a mixture of native C++ and .Net. You get easy access to both worlds, but those worlds doesn't really like being mixed ;)

EDIT: (*) As JochenKalmbach reminded, it applies to the "native" templates. Microsoft has prepared a special STL version that implements some of the core collection interfaces, hence its vector actually implements System.Collection.Generic.IEnumerable. That vector here is still subject to native restriction and cannot be published through asembly interface directly as itself (as vector<>). However, the latter type (IEnumerable) is completely normal CLR type and can be exposed. So, try for example:

System::Collections:::Generic::ICollection<int>^ MyClass::ListOfNumbers()
{
    cliext::vector<int>^ devs = gcnew cliext::vector<int>();
    devs->push_back(1);
    return devs;
}

It probably will compile - but I've not checked.



回答2:

cliext::vector is not intended to be used accross assembly boundaries. It can only be used inside your C++/CLI project. So add a "private:" and return an "IEnumerable" in the public interface.



回答3:

Yes, you can return collection. check this link

http://msdn.microsoft.com/en-us/library/bb385659.aspx

Although if you want to use this method in .NET framework or Native C++ you have to convert this collection to compatible collection of that particular language.