Alexander Van Atta
Alexander Van Atta

Reputation: 890

Wrapping a C++ function that takes int* in C++/cli

I am trying to wrap a C++ class in C++/cli a skeleton of the class is below.

public class UnmanagedClass{
  //...
  // This function stores the size in the x and y values
  int GetSize(int* x, int* y); 
};

I want make a managed class that wraps this class so I tried the following:

public ref class ManagedCode{
   UnmanagedClass* _pUnamangedClass;
   //...

   int GetSize(int% x, int% y){
      return _pUnmanagedClass->GetSize(&x,&y)
      // Also Tried
      // return _pUnmanaged->GetSize(x,y)
   };
};

I am getting a error: "internal_ptr is incompatible with parameter type "int*" "

return _pUnmanagedClass->GetSize(&x, &y)

Any ideas on where I am going wrong.

Upvotes: 1

Views: 128

Answers (2)

Hans Passant
Hans Passant

Reputation: 942000

The passed x and y arguments may be members of a managed object. When the garbage collector moves that object while the native code runs then disaster strikes, the native code corrupts the GC heap. The compiler detects that and disallows the code.

You'll have to provide the native code with a stable address. Like a local variable of a function, stored on the stack frame. Not pretty but it solves the problem:

   int GetSize(int% x, int% y){
      int xcopy = x;
      int ycopy = y;
      int retval = _pUnmanagedClass->GetSize(&xcopy, &ycopy);
      x = xcopy;
      y = ycopy;
      return retval;
   }

Or make this look like .NET code that any C# programmer will know how to use, I have to guess at the return value intention:

   Size GetSize() {
       int w, h;
       if (_pUnmanagedClass->GetSize(&w, &h) != 0) throw gcnew MyInteropException;
       return Size(w, h);
   }

Upvotes: 2

Alexander Van Atta
Alexander Van Atta

Reputation: 890

I have found a solution:

int GetSize(int% x, int% y){
   int xVal = x;
   int yVal = y;

   int result = _pUnmanagedClass->GetSize(&xVal, &yVal);

   x = xVal;
   y = yVal;

   return result;
};

Not sure why this works and the other does not.

Upvotes: 0

Related Questions