Запустить действие C ++ из события C# - PullRequest
1 голос
/ 07 февраля 2020

извините, если вопрос слишком общий, но я хотел бы знать, какое решение лучше.

У меня есть два проекта. Основной находится в C ++ и должен получать некоторую информацию от программного компонента. Для этого он использует. NET dll, который я написал в C#, и получает информацию от компонента программного обеспечения с использованием библиотек. NET. Я напишу простой CLI-проект, чтобы получить информацию, которую получает мой C# проект.

Итак, моя проблема в том, что у проекта C# много подписок на события и ему необходимо получать асинхронную информацию от программный компонент. Итак, я не знаю, как вызвать действие в C ++ (мой основной проект, который использует это. NET dll, чтобы запросить информацию из программного компонента), чтобы сохранить все данные, которые были собраны в этот момент.

Например, у меня есть подписка на это событие в проекте C#:

    private void SubscribeMessages()
    {
        comm.Comms.Subscribe(new Action<LoadFilterEVENTMessage>(LoadFilterEVENT));
    }

    private void LoadFilterEVENT(LoadFilterEVENTMessage msg)
    {
        FilterValue = msg.Filter;
    }

Итак, я хотел бы, чтобы этот LoadFilterEVENT дал C ++ знать, что он уже имеет значение фильтра. Любой намек?

Спасибо заранее:)

1 Ответ

2 голосов
/ 10 февраля 2020

Вот решение:

1 - Ваша C# dll должна загрузить C ++ SubscribeMessages DLL , которая будет использоваться для уведомления программы, используя метод DispatchEvents:

using System.Runtime.InteropServices;

namespace MyCSharpDLL
{
    class PlatformInvokeTest
    {
        // Import C++ DLL
        [DllImport("SubscribeMessages.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void DispatchEvents();

        static void LoadFilterEVENT(/*LoadFilterEVENTMessage msg*/)
        {
            //FilterValue = msg.Filter;
            DispatchEvents();
        }

        /* Methods in DLL being used below  */
        public static void Main()
        {
            LoadFilterEVENT();
        }
    };
}

2- Функция DispatchEvents принадлежит SubscribeMessages.dll (простой проект C ++ dll) выполняет роль бинарного семафора для разблокировки программы C ++:

extern "C" __declspec(dllexport) void DispatchEvents()
{
    // Juste open Semaphore
    HANDLE ghSemaphore = OpenSemaphore (SEMAPHORE_ALL_ACCESS , TRUE, _T("SemSubscribeMessages"));
    if ( NULL == ghSemaphore)
    {
        MessageBox(NULL,_T("Error when opening semaphore"),_T("Error"),0);
        return;
    }

    // Release semphare in order that CPP program can be notified
    ReleaseSemaphore(ghSemaphore,  1, NULL);
}  

Наконец, ваша C ++ программа должна ждать на семафоре SemSubscribeMessages, чтобы иметь возможность получать уведомления.
Поскольку ожидание блокируется, я поместил функцию WaitForSingleObject в отдельный поток , что обеспечивает большую гибкость для вашей основной программы:

#include <windows.h>
#include <iostream>
using namespace std;

 // Init value = 0 to block on the first call
#define INITIAL_COUNT 0

// Max value 1 to be a binarySemaphore
#define MAX_SEM_COUNT 1


DWORD WINAPI ListenNewEvent (LPVOID lpParam )
{
    DWORD  dwWaitResult;
    HANDLE ghSemaphore = CreateSemaphore( NULL, INITIAL_COUNT, MAX_SEM_COUNT, _T("SemSubscribeMessages"));

    if ( NULL == ghSemaphore) return -1;

    while (true)
    {
        cout<< _T("Wainting for new Events ...")<<endl;
        dwWaitResult = WaitForSingleObject( ghSemaphore, INFINITE);
        MessageBox(NULL,_T("New Event arrive ..."), _T("Notification"),0);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD   dwThreadId;
    HANDLE  hListnerThread = CreateThread( NULL, 0,  ListenNewEvent, NULL,  0, &dwThreadId);   

    WaitForSingleObject (hListnerThread, INFINITE);

    return 0;
}

Результат:
При запуске основной программы CPP вы получаете:

enter image description here

После C# dll отправив уведомление, вы получите:

enter image description here

Если вам нужно также обмениваться данными (помимо событий), вы можете добавить слой «совместно используемой памяти» после уведомлений ... надеясь, что это помогло вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...