## 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.

1. Open Microsoft® Visual Studio® and create a new Class Library (.NET Framework) project named `IMultiply`.

2. In the Solution Explorer window, rename the `Class1.cs` file to `IMultiply.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 of `multiply`:

``````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.

3. Go to Build and then Configuration Manager, and change the platform from Any CPU to x64.

4. 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.

1. Create a Library Compiler project and select .NET Assembly from the Type list.

2. Specify the following values:

FieldValue
Library Name`Multiply`
Class Name`Arithmetic`
File to Compile`multiply.m`

3. Expand the Additional Runtime Settings section.

4. In the Type-Safe API section, do the following:

1. Select Enable Type-Safe API.

2. In the Interface assembly field, specify the location of the type-safe interface assembly `IMultiply.dll` that you built.

3. Select the `IMultiply` interface from the .NET interface drop-down box.

4. Leave the Namespace field blank.

5. Specify the `Arithmetic` class in the Wrapped Class field.

5. 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.

1. 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'); ```
2. Navigate to the generated `MultiplydotNETAssembly` folder.

3. 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™ class `Arithmetic` in the namespace `MultiplyNative`.

### 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:

1. Open Microsoft Visual Studio and create a C# Console App (.NET Framework) called `MultiplyApp`.

2. 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; } } } ``````
3. 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. The `MWArray` data types are hidden behind the type-safe API in `ArithmeticIMultiply`.

4. Go to Build and then Configuration Manager, and change the platform from Any CPU to x64.

5. 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 output `z` appears before the inputs `x` and `y`. 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 named `multiply`, 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 for `out`, as `ref` and `out` 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.
{"ft_lang_label":"__label__en","ft_lang_prob":0.56510043,"math_prob":0.8010346,"size":9274,"snap":"2023-14-2023-23","text_gpt3_token_len":2130,"char_repetition_ratio":0.15285869,"word_repetition_ratio":0.026686434,"special_character_ratio":0.23948674,"punctuation_ratio":0.18657565,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9926452,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-03-21T17:44:49Z\",\"WARC-Record-ID\":\"<urn:uuid:fcb409cb-e64f-4c89-ba1d-5448c779a513>\",\"Content-Length\":\"91740\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:de845de5-1375-4c5a-afd5-1d4bcf3d18bb>\",\"WARC-Concurrent-To\":\"<urn:uuid:1b6d05c8-bdb9-426e-a058-a5ca7f2a20f5>\",\"WARC-IP-Address\":\"104.86.80.92\",\"WARC-Target-URI\":\"https://la.mathworks.com/help/compiler_sdk/dotnet/implement-type-safe-interface-and-generate-api-1.html\",\"WARC-Payload-Digest\":\"sha1:V7WCQ7DQ4JJPWCQAD5JTWFQGQBG6YHCE\",\"WARC-Block-Digest\":\"sha1:4U6VFWTNE3MY247JDXI6UX4URZCH7IAS\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-14/CC-MAIN-2023-14_segments_1679296943704.21_warc_CC-MAIN-20230321162614-20230321192614-00361.warc.gz\"}"}