Pregunta

This is maybe an obvious question but I have been googling for 2 hours and can't figure it out. So I've got a class in C++ that looks like this:

class MyClass
{
public:
  static void Function(float& r) { r = 10; }
};

I have an interop wrapper class that looks like this:

public ref class Wrapper
{
public:
    static void WrappedFunction(float& r) { MyClass::Function(r); }
};

And now I want to call it from C#, like this:

float r;
Wrapper.WrappedFunction(ref r);

However I get a compile error on the C# side which says this:

 cannot convert from 'ref float' to 'float*'

I have a vague notion that I need to do something in the Wrapper class but I don't know what. Also, I know this use case is trivial with dllimport/pinvoke but I want to wrap this with C++/CLI for performance reasons.

Any help is greatly appreciated!

¿Fue útil?

Solución

Wrapper class needs to be

public ref class Wrapper
{
public:
    static void WrappedFunction(float% r)
    { float copy = r; MyClass::Function(copy); r = copy; }
};

References defined with % work almost exactly like ones defined using &, except they work together with the garbage collector.

Another option is

public ref class Wrapper
{
public:
    static void WrappedFunction(float% r)
    { pin_ptr<float> p = &r; MyClass::Function(*p); }
};

Which will pin the object in memory preventing the garbage collector from using it, but have the native code work directly on the managed variable. Not usually important, but if you had another thread needing to see intermediate values, this is how.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top