1
votes

I am having some trouble passing a C++/CLI object pointer to a native object.

The entire picture is the following:

  • I am new to C++ in general (doomed)
  • I am using a third party native C++ library to interface a blackmagic IO video card. In the API there is a very handy method to pass a pointer of the object that will handle the frame callback while they are captured by the card: SetCallback(Pointer to an object that implement an interface).
  • In the above SetCallback(Pointer) I would like to pass the pointer to my C++/CLI object. When I do so I get: cannot convert argument 4 from 'CLIInterop::Wrapper ^*' to 'IDeckLinkInputCallback *'

My final target is to handle the callback from C++ into C++/CLI and at this point pass the frame over to WPF (if I will ever get that far)

The line of code invoved are:

Call from CLIInterop::Wrapper object

d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);

Method header in the native C++ project:

__declspec(dllexport) bool  DeckLinkDevice::StartCapture(unsigned int videoModeIndex, IDeckLinkScreenPreviewCallback* screenPreviewCallback, bool applyDetectedInputMode, IDeckLinkInputCallback* callbackHandler);

Help!

2
You must declare a native C++ class that implements that interface. You can get back to managed code from that native class with gcroot<ManagedClass> or stackoverflow.com/a/2973278/17034Hans Passant

2 Answers

0
votes

It is clearly indicate that your this pointer is not a type IDeckLinkInputCallback

d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);
                                                            ^ this pointer is not a type IDeckLinkInputCallback

As you told that you have already implement interface IDeckLinkInputCallback in the class of this pointer. Double check whether you have done it. Instead of calling StartCapture from the member function of the class better call it from outside and provide full address of the object instead this pointer.

-1
votes

You cannot just pass a managed reference ("hat pointer" ^) when a native pointer is expected. The whole point of C++/CLI is the possibility to create "glue" code such as what you're missing.

Basically, you would have to create a native class that implements the native interface, which may contain the managed reference that you call back to. I'm not familiar with the BlackMagic video card's interface (I used to have to work with DVS video cards, but their software interfaces are probably hardly comparable), but the general logic for such a wrapper would be similar to this:

class MyDeckLinkInputCallback : IDeckLinkInputCallback
{
public:
    MyDeckLinkInputCallback(CLIInterop::Wrapper^ wrapper)
    {
        _wrapper = wrapper;

        // initialize to your heart's content
    }
private:
    CLIInterop::Wrapper^ _wrapper;

public:
    // TODO implement IDeckLinkInputCallback properly; this is just a crude example
    void HandleFrame(void* frameData)
    {
        // TODO convert native arguments to managed equivalents

        _wrapper->HandleFrame(...); // call managed method with converted arguments
    }
};