1

I would like to wrap a native library with C++/CLI. It's work with primitive type. But in the following case, it's more complicated :

interface ISampleInterface
{
    void SampleMethod();
}

public ref class NativeClassWrapper {
    NativeClass* m_nativeClass;

public:
    NativeClassWrapper() { m_nativeClass = new NativeClass(); }
    ~NativeClassWrapper() { delete m_nativeClass; }
    void Method(ISampleInterface ^i) {
        ???
        m_nativeClass->Method(i);
    }
};

How to wrap this ? Because the native code C++ doesn't know the ISampleInterface type... (Same question with a virtual class)

Thanks you.

2
  • 1
    Why does NativeClass::Method need access to ISampleInterface? As you noted, it can't use it, so you need a way to change the design. Commented Aug 1, 2013 at 12:35
  • The native code needs to access to a class which implements ISampleInterface. In this example, it's an interface, but it can be a class. The problem in this design is the native code doesn't know the type of the element manipulated by C++/CLI. I have no idea how to resolve this problem. Which does design use ? Thanks for your help. Commented Aug 1, 2013 at 12:49

2 Answers 2

2

There are some mistakes in the code snippet. Let's start with a clean example, declaring the native class first:

#pragma unmanaged
class INativeInterface {
public:
    virtual void SampleMethod() = 0;
};

class NativeClass {
public:
    void Method(INativeInterface* arg);
};

And the managed interface:

#pragma managed
public interface class IManagedInterface
{
    void SampleMethod();
};

So what you need is a native wrapper class that derives from INativeInterface so that you can pass an instance of it to NativeClass::Method(). All that this wrapper has to do is simply delegate the call to the corresponding managed interface method. Usually a simple one-liner unless argument types need to be converted. Like this:

#pragma managed
#include <msclr\gcroot.h>

class NativeInterfaceWrapper : public INativeInterface {
    msclr::gcroot<IManagedInterface^> itf;
public:
    NativeInterfaceWrapper(IManagedInterface^ arg) : itf(arg) {};
    virtual void SampleMethod() {
        itf->SampleMethod();
    }
};

Now your method implementation becomes easy:

void Method(IManagedInterface^ i) {
    NativeInterfaceWrapper wrap(i);
    m_nativeClass->Method(&wrap);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks you very much, it works fine. Do you know the equivalent of msclr::gcroot in JAVA ?
@user1886318: It looks like jobject is roughly equivalent to GCHandle, and you'd need to make your own RAII wrapper around that to make sure it automatically gets released when the native code no longer needs it. Or borrow one, but I don't think there's an official JNI-sanctioned wrapper.
2

If your native class needs to callback into .NET code, you need to use the gcroot template. Wuth this you can store the managed object in an unmanaged class. In this unmanaged class you can then use a native "callback" and then use the member stored in `gcroot´ to callback into managed code (ISampleInterface).

See also:

1 Comment

Thanks you, indeed I have to use gcroot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.