Reputation: 199
I have legacy c library and exported it all in a c++ class library. So far, I have problem with passing arguments of type double** which simply is an out 2D array. Here is my c++ method signature:
public: int GetVariableValues(double **time_values) {
return LegacyGetVariableValues(time_values);}
And here is my c# client call:
double[][] a;
Legacy.GetVariableValues(a);
However it does not work and I get type errors. Anyone knows how to pass **(out) of course without using unsafe tag in C# client.
Upvotes: 0
Views: 315
Reputation: 469
You don't need the C++/CLI library is this case, pinning a multidimensional array is harder than just pinning a one-dimensional array as you need to pin the inner arrays manually. If you do it with C#, the compiler does it automatically for you.
With C#, you can do this:
[DllImport('legacylibrary.dll')]
public static extern int LegacyGetVariableValues(double[][] timeValues);
For further reading, check http://msdn.microsoft.com/en-us/library/fzhhdwae(v=vs.110).aspx
Edit:
As you need the C++/CLI layer, you need to do something like this:
ref class Legacy {
public:
int GetVariableValues(array<array<double> ^> ^values) {
array<GCHandle> ^handles = gcnew array<GCHandle>(values->Length);
double **valuesPtr = calloc(sizeof(double *), values->Length);
int result;
for (int i = 0; i < values->Length; i++) {
handles[i] = GCHandle::Alloc(values[i]);
valuesPtr[i] = (double *)GCHandle::ToIntPtr(handles[i]).GetPointer();
}
result = LegacyGetVariableValues(valuesPtr);
for (int i = 0; i < values->Length; i++) {
handles[i].Free();
}
return result;
}
}
PS: Don't know if the syntax is completely correct as I don't write C++/CLI in a long time.
Upvotes: 2