locked
Asynchronous delegate invocation is not supported. RRS feed

  • Question

  • Hi

    I'm writing a program in MatLab. The idea is to call a C# class library (dll) that connects to a serial interface, gets some specified data and sends it back to the matlab program.

    When matlab calls the dll, it passes a callback function handle to it. When the SerialDataReceivedEventHandler pops up with the requested data, the matlab callback should be called from the dll... 

    The following code works for a C# program calling the dll function, but with Matlab I get an: "Unhandled .NET exception: Asynchronous delegate invocation is not supported."

    What exactly does this error mean:

    - Is my idea to have a dll generate an event for Matlab simply not possible?
    - Is there a mistake in my code?

    - Am I choosing the wrong approach, is tehre a better way?

    ----------------------------------------------------------------------------------------------------

    The ComInterface.dll code:

    using System;
    
    using System.IO.Ports;
    
    
    
    namespace ComInterface
    
    {
    
     // Prototype for MatLab callback function
    
     public delegate void AnswerEvent(object sender, string msg);
    
    
    
     public class RS232
    
     {
    
      static SerialPort port;
    
      public static AnswerEvent matlabCallback;
    
    
    
      // Function to setup and open the serial port
    
      public static SerialPort Open(string portName)
    
      {
    
       // Specify port settings
    
       port = new SerialPort(portName);
    
       port.BaudRate = 115200;
    
       port.Parity = Parity.Odd;
    
       port.StopBits = StopBits.One;
    
       port.Handshake = Handshake.None;
    
       port.ReadTimeout = 10;
    
       port.WriteTimeout = 10;
    
    
    
       // Open serial port
    
       if (! port.IsOpen)
    
       {
    
        port.Open();
    
       }
    
       
    
       // Clear runt buffer data
    
       port.DiscardInBuffer();
    
       port.DiscardOutBuffer();
    
    
    
       // Register serial port callback function
    
       port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
    
    
    
       // Just for debugging
    
       return port; 
    
      }
    
    
    
    
    
    
    
      // Function to read data from external device
    
      public static int ReadRegister(int addr, AnswerEvent fnc)
    
      {
    
       
    
       // Store Matlab callback function (could this be done differently?)
    
       matlabCallback = fnc;
    
    
    
       // Device stecific message protocol:
    
       // 1. Byte = Status (0x00 = Read)
    
       // 2. Byte = Address
    
       // 3.-6. Byte = 4 Byte Data
    
       byte[] sendMsg = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    
       sendMsg[1] = Convert.ToByte(addr);
    
    
    
       // Send read request to device
    
       port.Write(sendMsg, 0, 6);
    
    
    
       // Just for debugging
    
       return 1;
    
      }
    
    
    
    
    
    
    
      // Callback function from serial port
    
      public static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    
      {
    
       byte[] rcvMsg = new byte[6];
    
    
    
       // Read answer from external deice
    
       port.Read(rcvMsg, 0, 6);
    
    
    
       // Call event handler function in Matlab
    
       // => This leads to System error (Matlab crashes): ".NET unhandled exception: Asynchronous delegate invocation is not supported."
    
       matlabCallback(port, BitConverter.ToString(rcvMsg)); 
    
    
    
       // What happens here? Does program go to matlab and never come back? Is there another way to generate an event?
    
       // Better Question: Is MatLab still waiting to be called back???
    
      }
    
     }
    
    }
    
    

    ---------------------------------------------------------------------------------------------------

    The Matlab program that calls the ComInterface.dll:

    % MatLab function:
    
    function GetRegister()
    
    
    
     global done
    
     done = 0;
    
    
    
     NET.addAssembly('C:\ComInterface.dll');
    
     
    
     % Open serial port on COM1 Interface
    
     ComInterface.RS232.Open('COM1');
    
     
    
     % Read register 23 and call my_callback_fcn when done.
    
     ComInterface.RS232.ReadRegister(23, @my_callback_fcn);
    
     
    
     while done == 0
    
      % Make sure MatLab program is still running when my_callback_fcn is
    
      % called from ComInterface.dll
    
     end
    
    end
    
    
    
    
    
    % Callback function, called from ComInterface.dll 
    
    function my_callback_fcn(obj, string_arg)
    
    
    
     global done
    
     
    
     done = 1;
    
     % Print register content to MatLab console
    
     disp(string_arg)
    
     
    
    end

    ----------------------------------------------------------------------------------------------------

    System Components:

    - MatLab 7.11.0 2010b
    - Visual Studio 10
    - .NET Framework 4

    Thanks for any suggestions in advance.

    Simon

    • Moved by Andrew_Zhu Tuesday, February 22, 2011 3:39 AM (From:.NET 4: Windows Workflow Foundation)
    Friday, February 18, 2011 2:40 PM

Answers