使用 MATLAB 构建 COM 组件 - 第二部分






4.90/5 (10投票s)
2004 年 3 月 3 日
5分钟阅读

73690

1202
使用 MATLAB COMBuilder 工具箱构建可从任何支持 COM 的 IDE 调用 的 COM 组件。
引言
在上一篇文章中,我描述了在 MATLAB 中创建 COM 组件的基本步骤,该组件可在支持 COM 功能的任何语言或 IDE 中使用。创建完整功能 COM 组件所需的步骤包括:
- 向 COM Builder 对象添加类方法和属性
- 向 COM Builder 对象添加事件
- 创建类的实例
- 调用类实例的方法
- 处理
varargin
和varargout
参数 - 处理方法调用期间的错误
第一步(向 COM Builder 对象添加类方法和属性)已在上一篇文章中介绍,其他步骤将在本文中介绍。
向 COM Builder 对象添加事件
MATLAB COM Builder 支持事件或回调,通过简单的 MATLAB 语言 pragma 实现。您只需提供一个 MATLAB 函数存根,作为事件的原型,然后在客户端代码(Visual Basic、Visual C++ 等)中提供该函数的实现。最终效果是,当任何其他 MATLAB 函数调用事件函数时,调用将分派到客户端代码中的“事件处理程序”。
您可以通过在代码中添加 %#event
pragma 来将 MATLAB 函数转换为事件函数。MATLAB 将此语句解释为注释。当您将相同的函数包含为 COM Builder 对象上的方法时,编译器将生成该方法的出接口,该接口将该方法标识为事件。此出接口随后由客户端代码实现。以下是一些在代码中使用回调的示例:
- 在长时间运行的计算过程中,向客户端应用程序提供周期性反馈。例如,如果您有一个需要 n 次迭代的任务,您可以在每次迭代时发出一个事件来递增用户界面中的进度条。
- 在计算过程中发出警告,但继续执行任务。
- 将计算的中间结果返回给用户并继续执行任务。
以下伪代码说明了上一段的含义:
LongCalculation.m
function [x] = LongCalculation(n) %initialize x x = 0; % Run n iterations, callback every inc time for i=1:n progress(i); % Do some work on x... x = x + 1; end;
Progess.m
function progress(i) %#event %progress(i) is an event function %the client must implement the event i
当 LongCalculation
运行时,将调用事件函数 progress(i)
。在客户端,开发人员可以处理该事件,例如,显示一个进度条,以图形方式演示计算的进度。在 Visual Basic 中,事件处理程序如下所示:
Sub CLASS_progress(ByVal i As Variant)
CLASS 是用于类实例的变量名。请注意,如果您想在 Visual Basic 中使用您的组件,则必须使用 WithEvent
关键字声明您的组件的实例。
在 MATLAB 中,键入 comtool
运行 COM Builder GUI,然后创建一个新项目并命名为 Example_Event
。将 LongCalculation.m 和 Progress.m 添加到项目中并构建 COM 组件。
现在,运行 Visual Basic 并创建一个包含文本框 (txtNum
)、命令按钮 (cmdGo
) 和进度条的新窗体。有关窗体的更多详细信息,请参见图 1。将以下代码添加到窗体中:
Private WithEvents MyVar As Example_Event.Example_Event
Private Sub Form_Load()
Set MyVar = New Example_Event.Example_Event
End Sub
Private Sub cmdGo_Click()
Dim d As Double
d = CDbl(txtNum.Text)
ProgressBar1.Max = d * 10
Call MyVar.longcalculation(0, 0, d * 10)
End Sub
Private Sub MyVar_Progress(ByVal i As Variant)
'Event handler. Called each time the LongCalculation function
'calls the Progress function. Progress bar is updated
'with the value passed in, causing the control to advance.
ProgressBar1.Value = i
End Sub
创建类的实例
创建类实例(或组件)实例很容易。Visual Basic 中有两种语法:
- 使用
CreateObject
函数 - 使用
New
运算符
在上面的部分中,您看到了如何使用 New
运算符。以下代码向您展示了如何使用 CreateObject
函数。
Private Sub Form_Load()
Dim myVar As Object
Set myVar = CreateObject("Fourier.Fourier")
Dim x(1 To 601) As Double
Dim t(1 To 601) As Double
m = 1
For i = 0 To 0.6 Step 0.001
t(m) = i
x(m) = Sin(2 * pi * 50 * t(m)) + Sin(2 * pi * 120 * t(m))
m = m + 1
Next
myVar.x = x
Call myVar.addnoise(0, 0)
Call myVar.powerspectrum(0, 0)
End Sub
在这种情况下,无需将 Fourier 类型库添加到项目中。程序会自动加载组件并在稍后使用它。如果您使用 New
运算符,则必须向项目添加引用。
调用类实例的方法
创建组件实例后,就可以调用其方法了。这些方法是 COM Builder 项目的 m 文件。在 Fourier 示例中(参见上一篇文章),我们声明了两个方法:AddNoise
和 PowerSpectrum
。它们都是我们添加到项目中的 m 文件(MATLAB 函数)。MATLAB 将它们编译为组件的方法。要调用这些方法,只需使用 Visual Basic 中的 Call
命令。这是一个示例:
Dim myVar As New Fourier.Fourier
Call myVar.addnoise(0, 0)
Call myVar.powerspectrum(0, 0)
当一个方法具有输出参数时,第一个参数始终是 nargout
,其类型为 Long
。此输入参数将正常的 MATLAB nargout
参数传递给编译后的函数,并指定请求的输出数量。没有输出参数的方法不传递 nargout
参数。紧随 nargout
之后的是输出参数,按它们在原始 MATLAB 函数左侧出现的顺序排列。接下来是输入参数,按它们在原始 MATLAB 函数右侧出现的顺序排列。所有输入和输出参数的类型均为 Variant
,这是 Visual Basic 的默认数据类型。
Variant
类型可以包含所有基本 VB 类型、任何类型的数组以及对象引用。通常,您可以将任何 Visual Basic 类型作为类方法的参数传递,但 Visual Basic UDTs 除外。当您将简单的变体类型作为输出参数传递时,被调用的方法会分配接收到的数据并释放 Variant
的原始内容。在这种情况下,将每个输出参数声明为单个 Variant
变量就足够了。当像 Excel Range 这样的对象类型作为输出参数传递时,对象引用会在两个方向上传递,并且对象的 Value
属性会接收数据。
以下示例向您展示了如何调用具有变体输入或输出的方法:
y = myfunction(x1, x2)
Dim myComponent As Object
Dim result As Variant
myComponent = CreateObject("Component.Component.1_0")
Call myComponent.myfunction(1, result, x1, x2)
处理 varargin 和 varargout 参数
当原始 MATLAB 函数中存在 varargin
和/或 varargout
时,这些参数将作为最后的输入/输出参数添加到类方法的参数列表中。您可以通过创建 Variant
数组,将数组的每个元素分配给相应的输入参数,来将多个参数作为 varargin
数组传递。
y = myfunction(varargin)
Dim myComponent As Object
Dim v(1 To 5) As Variant
Dim result As Variant
'x1, x2, x3, x4 and x5 are a value, vector or matrix
v(1) = x1
v(2) = x2
v(3) = x3
v(4) = x4
v(5) = x5
myComponent = CreateObject("Componen.Component.1_0")
Call myComponent.myfunction(1, result, v)
MWComUtil
实用程序库中包含的 MWUtil
类提供了 MWPack
辅助函数来创建 varargin
参数。有关详细信息,请参见以下示例:
varargout = myfunction(x1, x2)
Dim myComponent As Object
Dim Util As Object
Dim v As Variant
'Xin1 and Xin2 are a value, vector or matrix
Dim Xin1, Xin2 As Variant
Util = CreateObject("MWComUtil.MWUtil")
myComponent = CreateObject("Component.Component.1_0")
Call myComponent.myfunction(3, v, Xin1, Xin2)
Call Util.MWUnpack(v, 0, True, Xout1, Xout2, Xout3)
处理方法调用期间的错误
如果在创建组件实例或传递参数时发生任何错误,程序员可以捕获该错误并获取有关该错误及其原因的一些详细信息。在 Visual Basic 中处理错误的 easiest 方法是使用 On Error
语法。Err
全局变量包含有关错误的所需所有信息。例如:
On Error Goto Handle_Error
Dim Util As Object
Util = CreateObject("MWComUtil.MWUtil")
...
Handle_Error:
MsgBox(Err.Description)
尽情享用!