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

2019-08-10 21:32发布

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?

3条回答
男人必须洒脱
2楼-- · 2019-08-10 21:51

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.

查看更多
混吃等死
3楼-- · 2019-08-10 21:56

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.

查看更多
干净又极端
4楼-- · 2019-08-10 22:12

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.

查看更多
登录 后发表回答