Easiest way to send messages between Matlab, VB6 and VB.NET programs

We are updating a set of data collection and analysis routines from VB6 programs to a mixture of VB.NET, VB6 and Matlab programs. We want to keep a modular system (separate EXEs) so that we can easily create specialized standalone analysis programs without constantly updating one massive application. We used MBInterProcess to send messages between EXEs when all programs were written in VB6 and it worked great for us (for example to get the EXE data to send the last filename to the offline data mapper). Unfortunately this ActiveX cannot be used in Matlab or VB.NET to receive messages. We're wondering what the simplest string messaging system (pipes, logged messages, etc.) is that we could accept. Now we're just checkingwhether the new file was written in a specific folder, which may not be the best solution. Our ideal solution will not require a lot of investment in learning Windows nuances (we are biologists, not full-time programmers) and will work on both WinXP and 64-bit Windows.

In response to requests, we wrapped the entire Matlab session in a VB6 program that has an MBInterProcess ActiveX control. This works, but it is not a great solution for us, as it will probably lock us in WinXP forever (and of course, it won't let us use the 64-bit version of Matlab). The latest version of Matlab (2009a) can access .NET functions directly, so we assume that one solution might be to use a .NET library to implement pipes (or something similar) in programs. We would like to recreate the neatly simple MBInterProcess ActiveX syntax and a piece of code that listens for the message with the top-level Windows name of this program, and then calls a specific Matlab m file or VB.NET function using string data (such as a file name) as an argument.

0


a source to share


2 answers


Could you create an ActiveX EXE in VB6 to just forward messages between different parties? When someone called it, it will raise an event with the parameters passed to the call. Your VB6 and VB.NET code can set a link to the exe ActiveX to invoke it and drown its events. I'm not familiar with Matlab, so I don't know if it will be available there.

EDIT: You wrote that Matlab 2009a can access .NET directly. If it can lose .NET events, you can also have a .NET wrapper on a VB6 ActiveX EXE.

Here's some sample code that I quickly got down to.

VB6 ActiveX EXE project named VB6MatlabMessenger. Each message has a Destination text string (which somehow identifies the intended recipient) and a message string.

'MultiUse class VB6Messenger
Option Explicit

Public Event MessageReceived(ByVal Destination As String, ByVal Message As String)

Public Sub SendMessage(ByVal Destination As String, ByVal Message As String)
  Call Manager.RaiseEvents(Destination, Message)
End Sub

Private Sub Class_Initialize()
  Call Manager.AddMessenger(Me)
End Sub

Friend Sub RaiseTheEvent(ByVal Destination As String, ByVal Message As String)
  RaiseEvent MessageReceived(Destination, Message)
End Sub

'BAS module called Manager
Option Explicit

Private colMessengers As New Collection

Sub AddMessenger(obj As VB6Messenger)
  colMessengers.Add obj
End Sub

Sub RaiseEvents(ByVal Destination As String, ByVal Message As String)
  Dim obj As VB6Messenger
  For Each obj In colMessengers
    Call obj.RaiseTheEvent(Destination, Message)
  Next obj
End Sub

      



And a test VB6 normal exe with a link to VB6MatlabMessenger. Here is the entire frm file. Build this as an exe, run multiple copies. Fill in the input fields and text messages and click the button - you will see messages received in all exes (reported in the lists).

VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   3090
   ClientLeft      =   60
   ClientTop       =   450
   ClientWidth     =   4680
   LinkTopic       =   "Form1"
   ScaleHeight     =   3090
   ScaleWidth      =   4680
   StartUpPosition =   3  'Windows Default
   Begin VB.ListBox lstEvents 
      Height          =   1620
      Left            =   120
      TabIndex        =   3
      Top             =   1320
      Width           =   4455
   End
   Begin VB.TextBox txtMessage 
      Height          =   375
      Left            =   120
      TabIndex        =   2
      Text            =   "Message"
      Top             =   840
      Width           =   2295
   End
   Begin VB.TextBox txtDestination 
      Height          =   375
      Left            =   120
      TabIndex        =   1
      Text            =   "Destination"
      Top             =   240
      Width           =   2295
   End
   Begin VB.CommandButton cmdSendMessage 
      Caption         =   "Send Message"
      Height          =   495
      Left            =   2640
      TabIndex        =   0
      Top             =   360
      Width           =   1575
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private WithEvents objMessenger As VB6MatlabMessenger.VB6Messenger

Private Sub cmdSendMessage_Click()
  objMessenger.SendMessage txtDestination, txtMessage.Text
End Sub

Private Sub Form_Load()
  Set objMessenger = New VB6MatlabMessenger.VB6Messenger
End Sub

Private Sub objMessenger_MessageReceived(ByVal Destination As String, ByVal Message As String)
  lstEvents.AddItem Now() & " RECEIVED - " & Destination & ", " & Message
End Sub

      

I started writing a VB.NET class library that wraps VB6 to make it available to .NET. I have not tested this one. It has a link to VB6MatLabMessenger.

Public Class VBNETMatlabMessenger
  Private WithEvents objVB6Messenger As VB6MatlabMessenger.VB6Messenger

  Public Event MessageReceived(ByVal Destination As String, ByVal Message As String)

  Public Sub SendMessage(ByVal Destination As String, ByVal Message As String)
    objVB6Messenger.SendMessage(Destination, Message)
  End Sub

  Public Sub New()
    objVB6Messenger = New VB6MatlabMessenger.VB6Messenger
  End Sub

  Private Sub objVB6Messenger_MessageReceived(ByVal Destination As String, ByVal Message As String) Handles objVB6Messenger.MessageReceived
    RaiseEvent MessageReceived(Destination, Message)
  End Sub
End Class

      

This can get you started. Note that VB6 messenger objects will live forever, because the messenger keeps references to them internally, so COM will never clean them up. If this becomes a problem (if a lot of messages are sent without restarting the PC), you can add a method to Messenger VB6 that instructs it to remove the messenger object from its collection.

+1


a source


I used the Matlab dos command to execute a Java program on the command line, it waits for the command line to complete before returning control to Matlab. This worked for me, after my Matlab program recovered, I read the output file from Java.

I used compiled Matlab programs (i.e. exe), they work fine, but they dump files while they are running - I believe it is possible to pass command line arguments to the compiled executable. Assuming VB.NET is similar to C # .NET, you can execute the exe from code using something like a Process object.

Alternatively, there are ways to compile to .dll available via .NET, see here:



http://www.codeproject.com/KB/dotnet/matlabeng.aspx

for an explanation. I've never tried this ...

0


a source







All Articles