Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Building COM Components Using MATLAB - Part II

0.00/5 (No votes)
2 Mar 2004 3  
Building COM components that can be called from any IDE that supports COM with MATLAB COMBuilder toolbox.

Introduction

In the previous article, I described basic steps to create a COM component in MATLAB that can be used in any language or IDEs supporting COM features. The required steps for creating a full feature COM component are:

  • Adding Class Methods and Properties to COM Builder Objects
  • Adding Events to COM Builder Objects
  • Creating an Instance of a Class
  • Calling the Methods of a Class Instance
  • Processing varargin and varargout Arguments
  • Handling Errors During a Method Call

The first step (Adding Class Methods and Properties to COM Builder Objects) was described in the previous article and the others will be described here.

Adding Events to COM Builder Objects

MATLAB COM Builder supports events, or callbacks, through a simple MATLAB language pragma. You simply provide a MATLAB function stub that serves as the prototype for the event, and then provide an implementation of the function in your client code (Visual Basic, Visual C++, etc.). The net effect is that when any other MATLAB function calls the event function, the call is dispatched to the �event handler� in the client code.

You can turn a MATLAB function into an event function by placing a %#event pragma into the code. MATLAB interprets this statement as a comment. When you include the same function as a method on a COM Builder object, the compiler generates an outgoing interface for the method, which identifies the method as an event. This outgoing interface is then implemented by the client code. Some examples of how you might use callbacks in your code are:

  • To give a client application periodic feedback during a long running calculation. For example, if you have a task that requires n iterations, you might signal an event to increment a progress bar in the user interface on each iteration.
  • To signal a warning during a calculation but continue execution of the task.
  • To return intermediate results of a calculation to the user and continue execution of the task.

The following pseudo code illustrates the meaning of the above paragraph:

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

When LongCalculation runs, the event function progress(i) will be called. In client side, developer can handle the event, for example, show a progress bar that graphically demonstrates the progress of the calculation. In Visual Basic, the event handler looks like this:

Sub CLASS_progress(ByVal i As Variant)

The CLASS is the name of a variable used for class instance. Notice that if you want to use your component in Visual Basic, you must declare an instance of your component with WithEvent keyword.

In MATLAB, type comtool to run COM Builder GUI, then create a new project and name it Example_Event. Add LongCalculation.m and Progress.m to the project and build the COM component.

Now, run Visual Basic and create a new form consisting of a text box (txtNum), a command button (cmdGo) and a progress bar. See figure 1 for more details of the form. Add the following code to the form:

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

Creating an Instance of a Class

Creating an instance of a class (or a component) is easy. There are two types of syntaxes in Visual Basic:

  • Using CreateObject function
  • Using New operator

In the above section, you see how can use New operator. Following code shows you how to use CreateObject function.

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

In this situation, there is no need to add Fourier type library to the project. The program automatically loads the component and uses it later. If you employ New operator, you must add a reference to the project.

Calling the Methods of a Class Instance

After creating an instance of the component, it is possible to call methods of it. These methods are m-files of COM Builder project. In Fourier example (See previous article), we declared two methods: AddNoise and PowerSpectrum. Both of them are m-files (MATLAB functions) that we added to the project. MATLAB compiled them as methods of the component. For calling the methods, simply use Call command from Visual Basic. Here is an example:

Dim myVar As New Fourier.Fourier

Call myVar.addnoise(0, 0)
Call myVar.powerspectrum(0, 0)

When a method has output arguments, the first argument is always nargout, which is of type Long. This input parameter passes the normal MATLAB nargout parameter to the compiled function and specifies how many outputs are requested. Methods that do not have output arguments do not pass a nargout argument. Following nargout are the output parameters listed in the same order as they appear on the left side of the original MATLAB function. Next comes the input parameters listed in the same order as they appear on the right side of the original MATLAB function. All input and output arguments are typed as Variant, the default Visual Basic data type.

The Variant type can hold any of the basic VB types, arrays of any type, and object references. In general, you can supply any Visual Basic type as an argument to a class method, with the exception of Visual Basic UDTs. When you pass a simple variant type as an output parameter, the called method allocates the received data and frees the original contents of the Variant. In this case, it is sufficient to dimension each output argument as a single Variant. When an object type (like an Excel Range) is passed as an output parameter, the object reference is passed in both directions, and the object�s Value property receives the data.

Following examples show you how to call a method with variant inputs or outputs:

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)

Processing varargin and varargout Arguments

When varargin and/or varargout are present in the original MATLAB function, these parameters are added to the argument list of the class method as the last input/output parameters. You can pass multiple arguments as a varargin array by creating a Variant array, assigning each element of the array to the respective input argument.

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)

The MWUtil class included in the MWComUtil utility library provides the MWPack helper function to create varargin parameters. See following example for more details:

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)

Handling Errors During a Method Call

If any error occurred when creating an instance of a component or passing an argument, the programmer can catch the error and some detailed information about the error and reason of it. The easiest way for handling error in Visual Basic is On Error syntax. The Err global variable has all of the needed information about the error. E.g.:

On Error Goto Handle_Error
Dim Util As Object
Util = CreateObject("MWComUtil.MWUtil")
...
Handle_Error:
MsgBox(Err.Description)

Enjoy!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here