2

After search all over the internet for a 3 days - I need your help. I am trying to implement c++ interface from c# (with CLI layer in middle of them).

The problem (See in cli layer code in FrameGrabber_wrapper.cpp) is to call to Register(...)

This question IS NOT seems to other questions. i.e: 1. gcroot cannot be use in c++ layer. 2. already tried to convert "IFrameListener_wrapper" to void* in cli layer and convert void* to IFrameListener in c++ layer.

I am already know to pass data from c++ to c# but in simple way. not with interface wrapping.

Here is my code:

c++ layer:

// FrameGrabber.h

#pragma once
#include "IFrameListener.h"



#ifdef CPPLAYER_EXPORTS
#define CPPLAYER_API __declspec(dllexport)
#else
#define CPPLAYER_API __declspec(dllimport)
#endif


class FrameGrabber
{
public:
    CPPLAYER_API void Register(IFrameListener* _frameListener);

    CPPLAYER_API void NotifyOnNewFrame(int number);

    CPPLAYER_API void Method();

private:
    IFrameListener* m_frameListener = nullptr;
};


// FrameGrabber.cpp

#include "stdafx.h"
#include "FrameGrabber.h"

void FrameGrabber::Register(IFrameListener* _frameListener)
{
    m_frameListener = _frameListener;
}

void FrameGrabber::NotifyOnNewFrame(int number)
{
    if (m_frameListener)
    {
        m_frameListener->OnFrameEvent(number);
    }
}

void FrameGrabber::Method() {
    for (size_t i = 0; i < 1000; i++)
    {
        NotifyOnNewFrame(i);
    }
}





// IFrameListener.h

#pragma once

    class IFrameListener
    {
    public:
        virtual void OnFrameEvent(int number) = 0;
    };

// IFrameListener.cpp
#include "stdafx.h"
#include "IFrameListener.h"

cli layer:

// FrameGrabber_wrapper.h

#pragma once
#include <vcclr.h>
#include <string>
#include "IFrameListener_wrapper.h"
#include "../cppLayer/FrameGrabber.h"

namespace NativeClassWrapperNameSpace1
{
    FrameGrabber* m_frameGrabber;



    public ref class FrameGrabber_wrapper
    {

    public:

        FrameGrabber_wrapper() { m_frameGrabber = new FrameGrabber(); }

        void Register(IFrameListener_wrapper^ _frameListener);

        void NotifyOnNewFrame(int number);

        void Method()
        {
            m_frameGrabber->Method();
        }

    private:
        IFrameListener_wrapper^ m_frameListener_wrapper = nullptr;

    };

}


// FrameGrabber_wrapper.cpp

#include "stdafx.h"
#include "FrameGrabber_wrapper.h"

void NativeClassWrapperNameSpace1::FrameGrabber_wrapper::Register(IFrameListener_wrapper^ _frameListener)
{
    m_frameListener_wrapper = _frameListener;

    // HERE I NEED TO CALL TO m_frameGrabber->Register(...)
    // BUT IFrameListener_wrapper^ IS NOT IFrameListener*

}

void NativeClassWrapperNameSpace1::FrameGrabber_wrapper::NotifyOnNewFrame(int number)
{
    if (m_frameListener_wrapper)
    {
        m_frameListener_wrapper->OnFrameEvent(number);
    }
}


// IFrameListener_wrapper.h
#pragma once
#include "../cppLayer/IFrameListener.h"

namespace NativeClassWrapperNameSpace1
{
    public interface class IFrameListener_wrapper
    {
    public:
        virtual void OnFrameEvent(int number) = 0;
    };
}


// IFrameListener_wrapper.cpp

#include "Stdafx.h"
#include "IFrameListener_wrapper.h"

c# layer:

// SomeClass

    class SomeClass : IFrameListener_wrapper
    {
        public void OnFrameEvent(int number)
        {
            Console.WriteLine("Got a new number: " + number);
        }
    }

// Main

        static void Main(string[] args)
        {
            Console.WriteLine("Start...");

            FrameGrabber_wrapper frgrw = new FrameGrabber_wrapper();
            SomeClass mtn = new SomeClass();

            frgrw.Register(mtn);

            frgrw.Method();

            Console.WriteLine("End!");
        }

PLEASE HELP ME!

Matan Marciano
  • 333
  • 4
  • 13
  • It is not very clear why you favored a complete interface to talk back to external code, it does significantly complicate everything. All you *really* need, from the looks of it, is a simple function pointer. For which you can write a matching delegate, Marshal::GetFunctionPointerForDelegate() gets you the pointer you can pass to the native code so it can make the callback. Always favor the KISS principle in interop code. – Hans Passant May 07 '17 at 10:13

0 Answers0