Implement Type-Safe Interface and Integrate into .NET Application
This example shows how to implement a type-safe interface and integrate it into a .NET application.
Type-safe interfaces allow you to work directly with familiar native data types instead
of using the MWArray
API. Adding a type-safe interface to a .NET assembly
creates an additional set of methods that accept and return native .NET types.
Write and Test Your MATLAB Code
Create your MATLAB® program and then test the code before implementing a type-safe interface. The functions in your MATLAB program must match the declarations in your native .NET interface.
For this example, save the following code as multiply.m
. The
function returns the multiplication of the inputs x
and
y
.
function z = multiply(x,y)
z = x * y;
Test the function at the MATLAB command prompt.
multiply([1 4 7; 2 5 8; 3 6 9],[1 4 7; 2 5 8; 3 6 9])
ans = 30 66 102 36 81 126 42 96 150
Implement Type-Safe Interface
After you write and test your MATLAB code, develop a .NET type-safe interface in either C# or Visual Basic®. This example uses provided C# source code for the interface.
Open Microsoft® Visual Studio® and create a new Class Library (.NET Framework) project named
IMultiply
.In the Solution Explorer window, rename the
Class1.cs
file toIMultiply.cs
. In this file, you write source code for the type-safe interface that accesses the component.In this example, the
IMultiply
interface is written in C# and specifies three overloads ofmultiply
:using System; public interface IMultiply { // Scalar multiplication System.Double multiply(System.Double x, System.Double y); // Multiply vector by a scalar, return a vector System.Double[] multiply(System.Double[] x, System.Double y); // Matrix multiplication System.Double[,] multiply(System.Double[,] x, System.Double[,] y); }
Each method in the interface must exactly match a deployed MATLAB function.
All methods have two inputs and one output (to match the MATLAB
multiply
function), though the parameter data type varies.Go to Build and then Configuration Manager, and change the platform from Any CPU to x64.
Build the project with Microsoft Visual Studio.
The file
IMultiply.dll
is generated in the build folder.
This example assumes your assembly contains only IMultiply
.
Realistically, it is more likely that the type-safe interface will already be part of a
compiled assembly. The assembly can be compiled even before the MATLAB function is written.
Create .NET Assembly Using Library Compiler App
Generate the type-safe interface with the .NET assembly using the Library Compiler app. Alternatively, if you want to create a .NET assembly from the MATLAB command window using a programmatic approach, see Create .NET Assembly Using compiler.build.dotNETAssembly.
Create a Library Compiler project and select .NET Assembly from the Type list.
Specify the following values:
Field Value Library Name Multiply
Class Name Arithmetic
File to Compile multiply.m
Expand the Additional Runtime Settings section.
In the Type-Safe API section, do the following:
Select Enable Type-Safe API.
In the Interface assembly field, specify the location of the type-safe interface assembly
IMultiply.dll
that you built.Select the
IMultiply
interface from the .NET interface drop-down box.Leave the Namespace field blank.
Specify the
Arithmetic
class in the Wrapped Class field.
Click the Package button to build the project.
Create .NET Assembly Using compiler.build.dotNETAssembly
As an alternative to the Library Compiler app, you can generate the type-safe interface using a programmatic approach using the following steps. If you have already created an assembly using the Library Compiler, see Integrate .NET Assembly into .NET Application.
Build the .NET assembly using the
compiler.build.dotNETAssembly
function. Use name-value arguments to specify the assembly name and class name.compiler.build.dotNETAssembly('multiply.m', ... 'AssemblyName','Multiply', ... 'ClassName','Arithmetic');
Navigate to the generated
MultiplydotNETAssembly
folder.Generate the type-safe interface by using the
ntswrap
command from MATLAB:ntswrap('-c','Multiply.Arithmetic', ... '-a','IMultiply.dll', ... '-i','IMultiply');
Not all arguments are compatible with each other. See
ntswrap
for details on all command options.Tip
If the
IMultiply.dll
assembly is not in the current folder, specify the full path.This command generates the assembly
ArithmeticIMultiply.dll
that contains a type-safe API for the MATLAB Compiler SDK™ classArithmetic
in the namespaceMultiplyNative
.
Integrate .NET Assembly into .NET Application
After creating your .NET assembly, you can integrate it into any .NET application. You can use this example .NET application code as a guide to write your own .NET application.
Compile the .NET program using Microsoft Visual Studio by doing the following steps:
Open Microsoft Visual Studio and create a C# Console App (.NET Framework) called
MultiplyApp
.Copy the following source code into the generated
Program.cs
in your project:using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MultiplyApp { class Program { delegate String VectorToString<T>(IEnumerable<T> v); delegate IEnumerable<String> MatrixToString<T>(T[,] m); static void Main(string[] args) { Console.WriteLine("\nStarting application...\n"); //Create an instance of the Type-safe API IMultiply m = new ArithmeticIMultiply(); // Scalar multiplication double x = 17, y = 3.14159; double z = m.multiply(x, y); System.Console.WriteLine("{0} * {1} = {2}\n", x, y, z); // Vector times scalar double[] v = new double[] { 2.5, 81, 64 }; double s = 11; double[] d = m.multiply(v, s); VectorToString<double> vec2str = (vec => vec.Select(n => n.ToString()).Aggregate((str, next) => str + " " + next)); System.Console.WriteLine("[ {0} ] * {1} = [ {2} ]\n", vec2str(v), s, vec2str(d)); // Matrix multiplication double[,] magic = new double[,]{ // 3x3 magic square { 8, 1, 6 }, { 3, 5, 7 }, { 4, 9, 2 } }; double[,] squareSquared = m.multiply(magic, magic); MatrixToString<double> mat2str = mat => mat.EnumerateRows<double>().Select(r => vec2str(r)); PrintParallel(mat2str(magic), " * ".Select(c => c.ToString()), mat2str(magic), " = ".Select(c => c.ToString()), mat2str(squareSquared)); Console.WriteLine("\nClosing application..."); } public static void PrintParallel<T>(params IEnumerable<T>[] sources) { int max = sources.Select(s => s.Count()).Max(); for (int i = 0; i < max; i++) { foreach (var src in sources) System.Console.Write("{0} ", src.ElementAt(i)); System.Console.WriteLine(); } } } public static class ArrayExtensions { public static IEnumerable<IEnumerable<T>> EnumerateRows<T>(this Array a) { return Enumerable.Range(0, a.GetLength(1)).Select(row => a.ToIEnumerable<T>().Skip(row * a.GetLength(0)).Take(a.GetLength(0))); } public static IEnumerable<T> ToIEnumerable<T>(this Array a) { foreach (var item in a) yield return (T)item; } } }
Add references in the project to the following files.
This reference: Defines: IMultiply.dll
The .NET native type interface assembly IMultiply
ArithmeticIMultiply.dll
The generated type-safe API MultiplyNative.dll
The generated .NET assembly Note
Unlike other .NET deployment scenarios, you do not need to reference
MWArray.dll
in the server program source code. TheMWArray
data types are hidden behind the type-safe API inArithmeticIMultiply
.Go to Build and then Configuration Manager, and change the platform from Any CPU to x64.
Compile and run the program with Microsoft Visual Studio.
The program displays the following output:
Starting application... 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 Closing application...
Tips
In a MATLAB function, declaration outputs appear before inputs. For example, in the
multiply
function, the outputz
appears before the inputsx
andy
. This ordering is not required for .NET interface functions. Inputs may appear before or after outputs, or the two may be mixed together.MATLAB Compiler SDK matches .NET interface functions to public MATLAB functions by function name and argument count. In the
multiply
example, both the .NET interface function and the MATLAB function must be namedmultiply
, and both functions must have an equal number of arguments defined.The number and relative order of input and output arguments is critical.
In evaluating parameter order, only the order of like parameters (inputs or outputs) is considered, regardless of where they appear in the parameter list.
A function in the interface may have fewer inputs than its corresponding MATLAB function, but not more.
Argument mapping occurs according to argument order rather than argument name.
The function return value, if specified, counts as the first output.
You must use
out
parameters for multiple outputs.Alternately, the
ref
parameter can be used forout
, asref
andout
are synonymous.
MATLAB does not support overloading of functions. Thus, all user-supplied overloads of a function with a given name will map to a function generated by MATLAB Compiler SDK.
See .NET Types to MATLAB Types for complete guidelines in managing data conversion with type-safe interfaces.
See Also
compiler.build.dotNETAssembly
| ntswrap