Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Introducing Type Safe APIs with Builder NE

Guest blogger Peter Webb returns with another in an occasional series of postings about application deployment.

Contents

Life is Too Short to Write Boring Code

I can call MATLAB functions from C# using Builder NE. But MATLAB and C# have very different data types, so I spend a lot of time manually converting data from one system to the other. That kind of work is tedious and error-prone -- the C# compiler can't check to ensure that I'm passing the right type of data to my MATLAB functions.

Ideally, I'd like to be able to write MATLAB code that uses MATLAB data types and C# code that uses C# data types, and not have to worry about the conversion between them. Consider a very simple example, a MATLAB multiply function:

function z = multiply(x, y)
    z = x * y;

Though it looks simple, multiply behaves very differently depending on the type of its inputs. If the inputs are scalars, the result is a scalar, but if they are matrices, the result is the matrix product. And the numeric data type of the output (int32, double) varies with the type of the input.

In C#, I'd like to call multiply with scalars and matrices, and additionally to to support scalars times vectors. That's three ways to call multiply, and in C#, that means three separate functions:

double multiply(double x, double y)               // Scalar
double[,] multiply(double[,] x, double[,] y)      // Matrix
double[] multiply(double[] x, double y)           // Vector x Scalar

So far, that's nothing new -- I can do this today. I write each of these multiply functions myself, filling them up with code that converts .NET scalars, vectors and arrays to MATLAB matrices and vice versa. But it's boring, and I hate being bored.

So instead, I turn to the type safe APIs generated by Builder NE (as of version 4.0, R2011a), and let Builder NE write this code for me.

Type Safe APIs

Type Safe APIs allow you to specify a kind of contract between your C# code and your MATLAB functions. You describe exactly what kind of data you want to pass back and forth between MATLAB and C#, and Builder NE generates functions for those types only. You give up a little flexiblity (you can't pass just any type of data to your MATLAB function, like you could with the MWArray-based interface), but you gain type safety. Now the C# compiler can tell if you're doing something you shouldn't be, like passing strings to a function that operates on integers. (While this often completes without error, it very seldom produces a useful result.)

In C#, the usual mechanism for establishing such a contract is an interface. An interface defines the names and input and output types of one or more functions, but provides no implemention. We can collect our three multiply functions into the IMultiply interface. By convention, .NET interface names begin with a capitial I.

interface IMultiply
{
    // Scalar multiplication
    double multiply(double x, double y);
    // Multiply vector by a scalar, return a vector
    double[] multiply(double[] x, double y);
    // Matrix multiplication
    double[,] multiply(double[,] x, double[,] y);
}

The interface uses function overloading to take advantage of the polymorphism of the MATLAB function. The functions in the C# interface have the same name as the MATLAB function; Builder NE matches interface functions to MATLAB functions by name and number of arguments. (I'll discuss the details of argument matching in a later article.)

To use a type safe API, you'll need:

  • A MATLAB function
  • A C# interface that specifies the input and output types of that MATLAB function
  • A C# program that calls the MATLAB function through the C# interface.

The example demonstrates how to incorporate a type safe API into a C# program. In the example, you'll work through 4 basic steps:

  • Create a MATLAB function, multiply.
  • Define a C# interface IMultiply.
  • Compile multiply into a .NET component named Multiply and generate the type safe API MultiplyIMultiply.
  • Develop a C# main program that calls multiply through the IMultiply interface.
  • Since we've already seen the MATLAB code and the C# interface, let's take a look at the C# main program.

    Example C# Code

    You invoke MATLAB functions from C# by calling the instance methods of a Builder NE-generated component. Builder NE names the type safe API class by combining the names of the MATLAB function component (Multiply) and the C# interface (IMultiply). In this case, MultiplyIMultiply is the name of the type safe API class. Call new to create an instance of the component's type safe API class:

    // Create an instance of the Multiply component's type safe API.
    IMultiply m = new Multiply.MultiplyIMultiply();

    IMultiply publishes three multiply methods, one of which multiplies a vector and a scalar. Create the input data by declaring C# variables:

    // Create a C# vector and a scalar.
    double[] v = new double[]{ 2.5, 81, 64 };
    double s = 11;

    Finally, compute the product by calling multiply:

    // Multiply the vector and the scalar. Note: all inputs and outputs
    // are native C# types.
    double[] d = m.multiply(v, s);

    As usual in C#, passing the wrong type of inputs (if v had been declared as a string for example) results in compile-time errors.

    Building and Running the Example

    Download the source code from MATLAB Central into a new directory. The download contains the multiply MATLAB function and two Visual Studio projects. To create a runnable executable, you need to build the C# interface assembly, create a deploytool .NET assembly project for the MATLAB function and then link the main program against these two assemblies. The file ReadmeIntro.txt contains detailed instructions.

    The downloaded files compile into Multiplier.exe, a C# program that calls each of the methods in the IMultiply interface and prints the results. Make sure your runtime environment is set up correctly (you need either the MCR or MATLAB's runtime/<arch> directory on your path) and then locate and run Multiplier.exe from a DOS command window. The output should look something like this:

    17 * 3.14159 = 53.40703
    [ 2.5 81 64 ] * 11 = [ 27.5 891 704 ]
    8 1 6   8 1 6   91 67 67
    3 5 7 * 3 5 7 = 67 91 67
    4 9 2   4 9 2   67 67 91

    To enable other types of multiplcation, say vector times matrix or matrix times scalar, define the appropriate methods in IMultiply and then regenerate the Multiply component.

    More to Come

    To keep this post from turning into a book, I've discussed only the simplest and most common uses of Builder NE's type safe APIs. Forthcoming articles will reveal the secrets of parameter ordering, address the use of structured types (cell arrays and structures), and demonstrate how type safe APIs enable interprocess communication through the Windows Communication Foundation.

    In the meantime, please let me know what you think of this new feature. Will it make your job easier? How could we improve it even futher? Let us know here.




    Published with MATLAB® 7.12


    • print

    Comments

    To leave a comment, please click here to sign in to your MathWorks Account or create a new one.