Обратный вызов из C ++ в C# с использованием SWIG - PullRequest
4 голосов
/ 09 января 2020

У меня есть приложение, работающее в C# .Netcore и C ++ windows приложении.
Я достиг взаимодействия между C# & C ++ с помощью SWIG.

Но я не могу достичь функциональности Callback с C ++ до C#. Также я попытался передать указатель на функцию из C# в C ++. Но это также не удалось

Мое намерение состоит в том, чтобы добиться обратного вызова с помощью

  1. Передав указатель функции C# в C ++ и вызывая этот указатель функции при необходимости, чтобы C# функция будет выполнена.

  2. Создание базового класса с виртуальной функцией в C ++ и получение класса в C#, который реализует виртуальный метод. Установите для объекта производного C ++, чтобы я мог вызвать object-> VirtualMethod , чтобы вызвать функцию C#.

Но оба метода завершились неудачно.

'' ' Код C ++

    #pragma once
    #include <string>
    #include "TestDataClass.h"

    using namespace std;

    class EventHandlerBase
    {
    public:

        virtual void handle() = 0;

    };

    class TestClass
    {
    public:
        TestClass();
        ~TestClass();

        TestDataClass oData;
        TestDataClass* pData;

        int times2(int arg, string data);
        void SetData(TestDataClass data);
        void SetPointerData(TestDataClass* data);
        TestDataClass* GetPointerData();
        TestDataClass GetData();
        void Print();



        EventHandlerBase* EventObject;
        void SetEventObj(EventHandlerBase* data);


    };

' ''

'' ' Реализация C ++

#include "TestClass.h"
#include <iostream>

TestClass::TestClass()
{

}

TestClass::~TestClass()
{
}

int TestClass::times2(int arg, string data)
{
    return arg * 2;
}

void TestClass::SetData(TestDataClass data)
{
    this->oData = data;
}

void TestClass::SetPointerData(TestDataClass* data)
{
    this->pData = data;
}


void TestClass::Print()
{
    cout << this->oData.iData << endl;
    cout << this->oData.sData << endl;

    cout << this->pData->iData << endl;
    cout << this->pData->sData << endl;
    this->EventObject->handle();
}

TestDataClass* TestClass::GetPointerData()
{
    return this->pData;
}

TestDataClass TestClass::GetData()
{
    return this->oData;
}

void TestClass::SetEventObj(EventHandlerBase* data)
{
    if (data)
    {
        this->EventObject = data;
    }
    else
    {
        cout << "Event object is null" << endl;
    }
}

'' '

' '' Код интерфейса

%module CppTestApp

 %include <windows.i>
 %include <std_string.i>

 // generate directors for all classes that have virtual methods
%feature("director") EventHandlerBase; 

%{
    #include "TestClass.h"
    #include "TestDataClass.h"
%}


%include "TestClass.h"
%include "TestDataClass.h"

'' '

' '' C# Код

 class MyEventHandler : EventHandlerBase
    {
        public MyEventHandler() : base(System.IntPtr.Zero, false) { }
        public override void handle()
        {
            System.Console.WriteLine("handling event...");
        }
    }

 static void Main(string[] args)
        {
            TestClass cpp_File = new TestClass();

            MyEventHandler myEvent = new MyEventHandler();

            TestDataClass data = new TestDataClass() { iData = 10, sData = "Hello I am Object" };
            TestDataClass pData = new TestDataClass() { iData = 25, sData = "Hello I am Pointer" };

            Console.WriteLine(cpp_File.times2(1, "Haii").ToString());

            cpp_File.SetData(data);
            cpp_File.SetPointerData(pData);

            Console.WriteLine($"{cpp_File.GetData().iData}  ,  {cpp_File.GetData().sData}");
            Console.WriteLine($"{cpp_File.GetPointerData().iData}  ,  {cpp_File.GetPointerData().sData}");

            cpp_File.SetEventObj(myEvent);

            cpp_File.Print();


            Console.WriteLine("-----------------------------");
            Console.ReadLine();
        }

'' '

Когда я выполняю cpp_File.SetEventObj (myEvent); Значение объекта Cpp равно нулю. Поэтому я не могу вызвать виртуальную функцию.

Можете ли вы помочь мне в этом?

Кроме того, если это не правильный путь, то, пожалуйста, посоветуйте какой-нибудь метод для достижения Обратный вызов из C ++ в c# (с использованием SWIG) или с помощью любого другого метода в установить указатель функции из C# в C ++ (с использованием SWIG) .

Так что я могу установить указатель функции с C# на C ++ и добиться обратного вызова до C#, вызвав этот указатель на функцию

1 Ответ

3 голосов
/ 09 января 2020

Я получил ответ на вышеуказанный запрос, и я публикую его здесь. Вы также можете обратиться к this Link

После изменения кода интерфейса SWIG, как показано ниже, он работал для меня

'' ' Код интерфейса

%module (directors="1") CppTestApp


%{
    #include "TestClass.h"

    #include "TestDataClass.h"
%}


 %include <windows.i>
 %include <std_string.i>

%feature("director") EventHandlerBase;

%include "TestClass.h"
%include "TestDataClass.h"

'' '

' '' C# Код

class MyEventHandler : EventHandlerBase
    {

        public override void handle()
        {
            System.Console.WriteLine("handling event...");
        }
    }

'' '

...