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.
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.
a source to share
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 ...
a source to share