0

I'm working on converting one of our systems from C++ to c#. We're still using a lot of our C++ libraries in the new system.

I'm pretty new to C++ and interop stuff but until now I've managed to get by. One particular piece of code has been troubling me for a while. One of the C++ methods I'm calling:

Calibration::GetValues(const VARIANT FAR& Data, long count)

isn't behaving as expected. With similar methods in the library passing in a System.Array works. With this, no matter what I do no new values are written to the array. When I step into the code the expected values are being calculated and (as far as I can tell with my limited knowledge of C++ and memory management) written to the array. The moment the method is exited the array returns to its previous state.

I'm calling the method using

Array ar = Array.CreateInstance(typeof(float), count);

values.GetValues(ar, count);

I'm sure the solution is something pretty simple but I can't seem to work out what's going on.

EDIT:

I had a look through the metadata and the method is declared as

int GetValues(object Data, int Count);

I'm still trying to figure out how Interop works but hopefully this is what was asked for

OnABauer
  • 609
  • 4
  • 18
  • 1
    The problem will be in the declaration of the method on the C# side, which inconveniently you've not shown us. – Eric Lippert Mar 31 '14 at 12:38
  • Sorry if I haven't included enough in my question. What exactly is needed? The declaration of what method? – OnABauer Mar 31 '14 at 13:11
  • Somehow your C# program knows how to call `GetValues`. How does it know that? There's a declaration somewhere, possibly in metadata, possibly in source code. Odds are good that the marshalling metadata associated with it is wrong. – Eric Lippert Mar 31 '14 at 13:15
  • That makes sense. I think I need to research interop calls and marshalling. I'm new to the code base so still trying to work out what it all does. I'll look into what you've suggested – OnABauer Mar 31 '14 at 13:33
  • Do you have any [DllImport] in your code that you can show? – thepirat000 Apr 05 '14 at 04:50

2 Answers2

0

I haven't touched Interop in a long while but are you sure that making that call passes the pointer to the memory allocated array and not a copy of it? That would explain your "return to previous state" behavior.

Check out MSDN and more specifically the MarshalAs attribute options.

Adrian Zanescu
  • 7,907
  • 6
  • 35
  • 53
  • Arrays are a reference type, so no, a copy of the array would not be made when passed to a function. – Ed S. Apr 01 '14 at 07:36
  • @ED S. ref/value type semantics refer to clr calling sites. We are talking here about marshaling data between two different execution contexts (each have their own heaps etc.). Plus the behavior described matches what happens when you copy data. – Adrian Zanescu Apr 01 '14 at 09:26
  • That's true, I didn't consider funkiness in the marshalling. – Ed S. Apr 01 '14 at 16:39
0

You could try this :

Array ar = Array.CreateInstance( typeof( floa t ), count ) ;
object ar2pass = new object() ;
ar2pass = ar ;
values.GetValues( ar2pass, count );

Then ar2pass will be passed as reference as intended, and updated. I let you find more elegant ways to state

object ar2pass = new object() ;
ar2pass = ar ;
Olórin
  • 3,367
  • 2
  • 22
  • 42