简体   繁体   中英

Trigger a C++ action from a C# event

sorry if the question is too general, but I would like to know what is the best solution.

I have two projects. The main one is in C++ and needs to receive some information from a software component. For this it uses a .NET dll which I wrote in C# and receives the information from the software component using .NET libraries. I will write a simple CLI project to get the information that my C# project gets.

So, my problem is that the C# project has a lot of subscriptions to events and needs to receive asynchronously information from the software component. So, I don't know how to trigger an action in C++ (my main project which uses this .NET dll to ask for information from the software component) to save all data that has been collected at that point.

For instance, I have this event subscription in the C# project:

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

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

So, I would like that this LoadFilterEVENT let C++ know that it already has the filter value. Any hint?

Thank you in advanced :)

Here a solution :

1- Your C# dll need to load a C++ SubscribeMessages DLL which will be used to notify the program using the method 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- The function DispatchEvents belongs to SubscribeMessages.dll (simple C ++ dll project) has the role of releasing a binary semaphore to unlock the C++ program :

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);
}  

Finally, your C ++ program must wait on the SemSubscribeMessages semaphore to be able to receive notifications.
As the wait is blocking, I put the WaitForSingleObject function in a separate thread which allows more flexibility for your main program :

#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;
}

Result:
When you run the main CPP programme, you get :

在此处输入图片说明

After C# dll send a notification, you will get:

在此处输入图片说明

If your need is to share data too (in addition to events) you can add a "shared memory" layer after the notifications ... hoping this helped you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM