How do I pass a Generic::List by reference?
-
22-08-2019 - |
Question
In an attempt to wrap some unmanaged code in a managed .dll I'm trying to convert a Generic::List
of data points into a std::vector
. Here's a snippet of what I'm trying to do:
namespace ManagedDLL
{
public ref class CppClass
{
void ListToStdVec( const List<double>& input_list, std::vector<double>& output_vector )
{
// Copy the contents of the input list into the vector
// ...
}
void ProcessData( List<double> sampleData )
{
std::vector<double> myVec;
ListToStdVec( sampleData, myVec );
// Now call the unmanaged code with the new vector
// ...
}
}
}
Compiling this gives me:
error C3699: '&' : cannot use this indirection on type 'const System::Collections::Generic::List'
I've probably missed something fundamental here (I'm relatively new to .net's way of doing things), but that looks like reasonably valid code to me.. ?
[Edit] I've tried both Andy and Dario's suggestions and they work, but how do I then access the members of the input list? I've tried all sorts of combinations of dreferencing and nothing seems to compile:
void ListToStdVec( const List<double>% input_list, std::vector<double>& output_vector )
{
int num_of_elements = input_list->Count;
}
void ListToStdVec( const List<double>^ input_list, std::vector<double>& output_vector )
{
int num_of_elements = input_list.Count;
}
...both give me:
error C2662: 'System::Collections::Generic::List::Count::get' : cannot convert 'this' pointer from 'const System::Collections::Generic::List' to 'System::Collections::Generic::List %'
...so how do you access the reference / pointer?
Solution
As List<T>
is a managed .NET class, it's passed by managed GC-Handle denoted by ^ and not by C++-reference.
Ex:
void ListToVec(List<double>^ input_list, std::vector<double>& out)
You don't need additional const
here. The notation List<T>^%
creates a tracking reference (comparable to C++-pointers) rather than a call by reference.
Just access the members by list->...
and list[...]
.
OTHER TIPS
According to Herb Sutter, %
is the managed object pass by reference character. Convert the code to the following, and it should work:
void ListToStdVec( const List<double>% input_list, std::vector<double>& output_vector
{
// Copy the contents of the input list into the vector
// ...
}
Edit: I think the const
is causing the issues, although I'm not sure why. If you change the List
argument to not be const
, then the first function will compile if you use the ->
operator, while the second function will compile if you use the .
operator (I'm not sure why that difference exists - it doesn't make much sense).
That said, if all that you want to do is to copy the elements in the List
to the vector
, then you really want to use ^
. Think of that as having a reference to the managed object. I think that %
would be used if you want to pass the reference "by reference" (i.e. reassign input_list
to something else within ListToStdVec()
, and have the caller see the result of that assignment. However, given that you use the .
operator to access members when using %
, that tells me that I may not understand the purpose of that at all.