在Matlab,VB6和VB.NET程序之间发送消息的最简单方法

时间:2009-05-16 13:50:36

标签: vb.net vb6 matlab messages interprocess

我们正在将一套数据采集和分析程序从VB6程序升级到VB.NET,VB6和Matlab程序的混合体。我们希望保持系统模块化(单独的EXE),这样我们就可以轻松创建专门的独立分析程序,而无需不断升级一个大型应用程序。当所有程序都是用VB6编写时,我们使用MBInterProcess在EXE之间发送消息,这对我们来说非常有效(例如,让数据采集EXE将最新的文件名发送到独立的数据显示程序)。不幸的是,这个ActiveX不能在Matlab或VB.NET中用来接收消息。我们想知道什么是我们可以采用的最简单的字符串消息传递系统(管道,注册消息等)。现在我们只是轮询以查看新文件是否写入特定文件夹,这不是最佳解决方案。我们理想的解决方案不需要花费大量时间学习Windows的细微差别(我们是生物学家,而不是全职程序员),并且可以在WinXP和64位版本的Windows中使用。

为了响应查询,我们将整个Matlab会话包含在具有MBInterProcess ActiveX控件的VB6程序中。这可行,但对我们来说不是一个很好的解决方案,因为它可能永远锁定我们进入WinXP(当然会阻止我们使用64位版本的Matlab)。最新版本的Matlab(2009a)可以直接访问.NET函数,因此我们假设一种解决方案可能是使用.NET库来跨程序实现管道(或类似的东西)。我们想要重新创建MBInterProcess ActiveX的优雅简单语法,并拥有一段代码,用于侦听具有该程序的顶级Windows名称的消息,然后调用特定的Matlab m文件或VB.NET函数,字符串数据(例如,文件名)作为参数。

2 个答案:

答案 0 :(得分:1)

你能在VB6中创建一个ActiveX EXE来简单地在不同方之间转发消息吗?当有人调用它时,它会引发一个带有传递给调用的参数的事件。您的VB6和VB.NET代码可以建立对ActiveX exe的引用来调用它并接收它的事件。我不熟悉Matlab所以我不知道它是否可以在那里访问。

编辑:你写过Matlab 2009a可以直接访问.NET。如果它可以接收.NET事件,那么你也可以在VB6 ActiveX EXE上安装.NET包装器。

以下是我快速敲定的一些示例代码。

VB6 ActiveX EXE项目,项目名称为VB6MatlabMessenger。每条消息都有一个文本字符串Destination(以某种方式标识预期的收件人)和一个包含该消息的字符串。

'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

测试VB6正常exe,参考VB6MatlabMessenger。这是整个frm文件。将其构建为exe,运行几个副本。填写目的地和消息文本字段,然后单击按钮 - 您将看到消息是在所有 exes中接收的(在列表框中报告)。

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

我开始编写一个VB.NET类库,它包装了VB6,使.NET可以访问它。我没有测试过这个。它引用了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

这可能会让你开始。请注意,VB6 messenger对象将永远存在,因为messenger在内部保留对它们的引用,因此COM将永远不会整理它们。如果这成为问题(如果很多消息在没有重新启动PC的情况下发送),您可以向VB6 messenger添加一个方法,指示它从其集合中删除messenger对象,

答案 1 :(得分:0)

我已经使用Matlab dos命令在命令行上执行Java程序,它等待命令行完成,然后将控制权返回给Matlab。在我的Matlab程序重新获得控制权后,我从Java中读取了输出文件,这对我来说很好。

我已经使用了编译的Matlab程序(即exe),这些工作没问题,但是当它们执行时会喷出文件 - 我相信可以将命令行参数传递给已编译的可执行文件。假设VB.NET与C#.NET类似,您可以使用类似Process对象的代码从代码执行您的exe。

或者,有一些方法可以编译为.dll,可通过.NET访问,请参阅此处:

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

作出解释。我从未尝试过这个......

相关问题