C# callback from native C++ async thread

  asynccallback, c++, stdasync

I want call C# callback function from C++ native dll. This works OK in one thread, but does not work with async run. Please look at code and help me. I have put comment where I have issues.

C++ dll:

typedef void __cdecl CalbackCommand(uint8_t idCmd);

CalbackCommand* g_command;

void __cdecl ReadPort(CalbackCommand *cmdFunc)
{
    g_command(13);
}

extern "C" __declspec(dllexport) void __cdecl SetCommand(CalbackCommand& cmdFunc)
{
    g_command = cmdFunc;
}

extern "C" __declspec(dllexport) int Run(const char* portName, const unsigned long baudRate)
{
    g_command(33); // OK

    ReadPort(); // OK

    auto ftrReadFromArd13 = std::async(std::launch::async, ReadPort);
    ftrReadFromArd13.wait();
    
    return 0;
}

C# WinForm exe:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CalbackCommand(byte idCommand);

[DllImport("Bridge.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int Run(StringBuilder portName, ulong baudRate);

[DllImport("Bridge.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern void SetCommand([MarshalAs(UnmanagedType.FunctionPtr)] CalbackCommand cmdFunc);

//Form class
private CalbackCommand m_calbackCommand;

private void FormMain_Load(object sender, EventArgs e)
{
     m_calbackCommand = new CalbackCommand(receivedCommand);
     GC.KeepAlive(m_calbackCommand);            
     SetCommand(m_calbackCommand);           
}

private delegate void DelegateReceivedCommand(byte idCommand);

private void receivedCommand(byte idCommand)
{
    if (rchTxtBx.InvokeRequired)
    {
         rchTxtBx.Invoke(new DelegateReceivedCommand(receivedCommand), idCommand); // Here hang after std::async
    }
    else
    {
         rchTxtBx.AppendText("Cmd: " + idCommand); // Works OK for idCommand == 33
    }
}

receivedCommand(byte idCommand) works OK for the first two calls from Run. But does not work for call #3 from std::async. I see correct idCommand value in C# debugger but Invoke() line does not work.

Thanks!

Source: Windows Questions C++

LEAVE A COMMENT