0

我们正在将一套数据采集和分析例程从 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 函数,字符串数据(例如,文件名)作为参数。

4

2 回答 2

1

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

编辑:您已经写到 Matlab 2009a 可以直接访问 .NET。如果它可以接收 .NET 事件,您还可以在 VB6 ActiveX EXE 上使用 .NET 包装器。

这是我快速敲出的一些示例代码。

项目名称为 VB6MatlabMessenger 的 VB6 ActiveX EXE 项目。每条消息都有一个文本字符串 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 对象,

于 2009-05-16T15:24:10.097 回答
0

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

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

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

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

解释一下。这个我没试过。。。

于 2009-05-16T15:03:40.740 回答