将接受元胞数组作为输入参量的 MATLAB 函数部署到 .NET 应用程序
支持的 .NET 版本:.NET 6.0 或更高版本
数据 API:MATLAB® Data Array for .NET
此示例说明如何打包接受元胞数组作为输入的 MATLAB 函数,并使用用 C# 编写的 .NET 应用程序进行部署。Windows®、Linux® 和 macOS 系统支持此工作流。本示例使用基于 Windows 工作流。
自 R2023a 起,可以跨 Windows、Linux 和 macOS 平台开发和发布包含打包的 MATLAB 代码的 .NET 应用程序。这意味着可以在这三种平台中的任一平台上进行开发,然后发布到另外两个平台上。在此版本之前,.NET 应用程序只能从 Windows 发布到 Linux 和 macOS。
请注意,虽然开发和发布可以在任何平台上进行,但仍可能存在特定于平台的细微差别和问题。某些库或函数在不同平台上的行为可能会有所不同,开发人员应在目标平台上彻底测试他们的应用程序以确保预期的行为。
前提条件
创建一个对 MATLAB 搜索路径可见的新工作文件夹。此示例使用名为
work
的文件夹。验证您是否已设置 .NET 开发环境。有关详细信息,请参阅设置 .NET 开发环境。
验证您是否已满足所有 MATLAB .NET 目标要求。有关详细信息,请参阅MATLAB Compiler SDK .NET 目标要求。
最终用户必须安装 MATLAB Runtime 才能运行应用程序。有关详细信息,请参阅下载并安装 MATLAB Runtime。
出于测试目的,您可以使用安装的 MATLAB 来代替 MATLAB Runtime。
验证您是否已安装 .NET 6.0 SDK 或更高版本或 Microsoft® Visual Studio® 2022(v17.0 或更高版本)。您可以在系统命令提示符下输入
dotnet --info
来验证 .NET 6.0 是否已安装。您可以从 https://dotnet.microsoft.com/download 下载特定于您的操作系统的 .NET SDK 版本。
数据管理
要在部署的 MATLAB 代码和 .NET 应用程序之间交换数据,请使用适用于 .NET 的 MATLAB Data API。MATLAB 引擎也使用此 API。有关概述,请参阅从 .NET 调用 MATLAB。有关详细信息,请参阅:
创建 MATLAB 函数
使用以下代码创建一个名为 computeCellMean.m
的 MATLAB 文件:
function outputCell = computeCellMean(inputCell) % computeCellMean - Calculate mean values for data in a cell array. % This function takes a 2x2 cell array as input. The cell array is expected % to contain numeric arrays. It computes the mean of the numeric arrays % in the second column of each row and appends these mean values as new % elements in the corresponding rows. % Inputs: % inputCell - A 2x2 cell array. The first column can contain any data. % The second column should contain numeric arrays for which % the mean is calculated. % Outputs: % outputCell - A 2x3 cell array. The first two columns are the same as % inputCell, and the third column contains the calculated mean % values. % Use arguments block to map a MATLAB type to a C# type % Cell arrays in MATLAB map to a System.object in C# arguments (Input) inputCell (2,2) cell end arguments (Output) outputCell (2,3) cell end % Calculate mean temperature and mean pressure meanTemperature = mean(inputCell{1, 2}); meanPressure = mean(inputCell{2, 2}); % Copy inputCell to outputCell and append mean values outputCell = inputCell; outputCell{1,end+1} = meanTemperature; outputCell{2,end} = meanPressure; end
资深 MATLAB 用户可能会发现 arguments
模块的存在不太寻常。arguments
模块允许您用等效的 MATLAB 类型表示 C# 数据类型。
注意
MATLAB 元胞数组在 C# 中映射为 System.object
。有关详细信息,请参阅Data Type Mappings Between .NET and Strongly Typed MATLAB Code。
在命令提示符下测试 MATLAB 函数。
% Define the cell array data = { "temperatures", [72, 75, 69, 68, 70]; "pressures", [30, 29.5, 30.2, 29.9, 30.1] } % Call the function results = computeCellMean(data)
data = 2×2 cell array {["temperatures"]} {[72 75 69 68 70]} {["pressures" ]} {1×5 double } results = 2×3 cell array {["temperatures"]} {[72 75 69 68 70]} {[70.8000]} {["pressures" ]} {1×5 double } {[29.9400]}
使用 compiler.build.dotNETAssembly
创建 .NET 程序集
使用 compiler.build.dotNETAssembly
函数从 MATLAB 函数创建代码存档(.ctf
文件)。
buildResults = compiler.build.dotNETAssembly("computeCellMean.m", Interface="matlab-data",... Verbose="on", OutputDir=".\output", AssemblyName="CellStats")
尽管通过 AssemblyName
属性提供程序集名称不是强制性的,但强烈建议这样做。这样做会为生成的 .NET 程序集和 C# 文件提供更清晰的命名空间。如果没有它,名为 example
的根命名空间会自动追加到子命名空间,从而导致命名空间结构混乱且可能令人困惑。
该函数生成一套文件(如下所列),并将它们放在指定的 output
目录中。其中,集成过程中使用的关键文件是包含 MATLAB 代码的代码存档(.ctf
文件)、C# (.cs
) 代码文件和 .NET 程序集(.dll
文件)。有关其他文件的信息,请参阅打包 MATLAB 函数后生成的文件。
P:\MATLAB\WORK\OUTPUT │ CellStats.csproj │ CellStats.ctf │ CellStats.deps.json │ CellStats.dll │ GettingStarted.html │ includedSupportPackages.txt │ mccExcludedFiles.log │ readme.txt │ requiredMCRProducts.txt │ unresolvedSymbols.txt │ └───strongly_typed_interface computeCellMean.cs
要完成集成,您可以选择以下两个选项之一:
将
CellStats.ctf
代码存档文件与computeCellMean.cs
C# 代码文件结合使用。将
CellStats.ctf
代码存档文件与CellStats.dll
.NET 程序集文件结合使用。
经检查,您会注意到该函数还生成一个 CellStats.csproj
工程文件。该文件是专门为创建相应的 CellStats.dll
.NET 程序集文件而生成的。但是,它不应被误认为是 .NET 工程的模板,并且不得在该环境中使用。
此示例采用第一个集成选项来说明类型映射机制。在工作流的相关阶段插入了使用第二种选项的相关指导。
您可以检查以下 C# 代码文件的内容:
在 computeCellMean.cs
C# 代码文件中,MATLAB 函数的 cell
参量规范映射其 C# 等效项 System.object
。其别名通常为 object
,[,]
表示二维数组。
arguments (Input) inputCell (2,2) cell end | object[,] inputCell |
arguments (Output) outputCell (2,3) cell end | public static void computeCellMean(MATLABProvider _matlab, object [,] inputCell, out object [,] outputCell){ dynamic _dynMatlab = _matlab; outputCell = (object [,])_dynMatlab.computeCellMean(new RunOptions(nargout:1), inputCell); } |
将 MATLAB 代码集成到 .NET 应用程序中
您可以在首选的 C# 开发环境中完成集成过程,包括文本编辑器以及 .NET SDK 命令行 API,或者 Windows 和 Microsoft macOS 上的 Visual Studio 等替代方案。此示例向您说明如何使用两个选项完成集成。有关详细信息,请参阅设置 .NET 开发环境。
使用 .NET SDK 命令行 API 构建应用程序
如果您使用的是 Microsoft Visual Studio,请参阅使用 Microsoft Visual Studio 构建应用程序 (Windows)。
在 Windows 中打开命令提示符并导航到本示例中使用的
work
文件夹。在命令行中输入:
dotnet new console --framework net6.0 --name CellConsoleApp
此命令创建一个名为
CellConsoleApp
的文件夹,其中包含以下内容:obj
文件夹CellConsoleApp.csproj
工程文件Program.cs
C# 源文件
将由
compiler.build.dotNETAssembly
函数生成的以下文件与dotnet new
C# 应用程序代码文件一起复制到Program.cs
创建的工程文件夹中:来自
.cs
目录的...\work\output\strongly_typed_interface\
C# 包装器文件。来自
...\work\output
目录的代码存档CellStats.ctf
。
编辑工程以添加程序集依赖项和由
compiler.build.dotNETAssembly
函数生成的CellStats.ctf
代码存档文件。在文本编辑器中打开工程文件,并使用以下程序集包含
<Reference>
标记内的<ItemGroup>
工程标记:MathWorks.MATLAB.Runtime.dll
MathWorks.MATLAB.Types.dll
注意
如果您使用由
compiler.build.dotNETAssembly
函数生成的CellStats.dll
.NET 程序集而不是 C# 代码文件,请将其作为引用包含在同一个<ItemGroup>
标记。将
CellStats.ctf
代码存档文件作为内容文件包含到工程中。将
CellStats.ctf
代码存档文件作为内容文件添加进<ItemGroup>
标记。添加标记
CopyToOutputDirectory
并将其设置为Always
。此步骤确保在构建过程中将CellStats.ctf
文件复制到输出文件夹。这意味着当您构建工程时,该文件与您构建的.exe
文件位于同一目录中。添加标记
CopyToPublishDirectory
并将其设置为Always
。此步骤确保将CellStats.ctf
文件复制到此工程发布到的跨平台文件夹中。
一旦添加了程序集依赖项并将
CellStats.ctf
作为内容文件包含进来,您的工程文件将如下所示:CellConsoleApp.csproj
(Windows)注意
如果您选择在 C# 代码文件上使用由
compiler.build.dotNETAssembly
生成的CellStats.dll
.NET 程序集,请记住取消注释工程文件中对CellStats.dll
的引用标记。此更改可确保您的工程正确使用.dll
文件。将
Program.cs
C# 文件中的代码替换为以下代码:注意
在 macOS 系统上开发和操作时,将代码从
Main
方法转换到名为MainFunc
的新函数。随后,从MATLABRuntime.SetupMacRunLoopAndRun
方法中调用Main
,并将MainFunc
与命令行参量一起作为参数传递。MATLABRuntime.SetupMacRunLoopAndRun 对于 macOS 环境来说是不可或缺MATLABRuntime.SetupMacRunLoopAndRun
,因为它允许 MATLAB 与 Core Foundation Run Loop (CFRunLoop) 交互,这是一种特定于 macOS 的机制,用于处理用户输入或计时器事件等事件。有关详细信息,请参阅MathWorks.MATLAB.Runtime.MATLABRuntime
。在命令行中,输入以下命令来构建您的工程:
dotnet build CellConsoleApp.csproj
运行 C# 应用程序
为了测试目的,您可以从 MATLAB 命令提示符运行该应用程序。这不需要安装 MATLAB Runtime。
在 MATLAB 命令提示符下,导航到包含可执行文件的目录,然后输入以下内容运行您的应用程序:
!dotnet run
应用程序显示平均值。
INPUT temperatures [72.00, 75.00, 69.00, 68.00, 70.00] pressures [30.00, 29.50, 30.20, 29.90, 30.10] OUTPUT temperatures [72.00, 75.00, 69.00, 68.00, 70.00] 70.80 pressures [30.00, 29.50, 30.20, 29.90, 30.10] 29.94
注意
当您准备部署此应用程序时,请确保目标系统已安装 MATLAB Runtime。有关详细信息,请参阅下载并安装 MATLAB Runtime。在 Linux 和 macOS 系统上,必须在运行应用程序之前分别设置 LD_LIBRARY_PATH
和 DYLD_LIBRARY_PATH
运行时路径。有关详细信息,请参阅针对部署设置 MATLAB Runtime 路径。
使用 Microsoft Visual Studio 构建应用程序 (Windows)
打开 Microsoft Visual Studio 并创建一个名为
CellConsoleApp
的 C# Console App。选择
.NET 6.0 (Long-term support)
作为框架。将
Program.cs
文件中默认生成的源代码替换为此示例页面中的Program.cs
文件中提供的特定源代码。选择以下两个选项之一:
要合并由
compiler.build.dotNETAssembly
函数生成的computeCellMean.cs
C# 代码文件,请导航到 Solution Explorer,右键点击您的工程,然后选择 Add > Existing Item。使用对话框查找并添加computeCellMean.cs
C# 代码文件。如果您更喜欢使用由
compiler.build.dotNETAssembly
函数生成的CellStats.dll
.NET 程序集,请在 Solution Explorer 中右键点击您的解决方案,然后选择 Edit Project File。在这里,您需要在现有文件中添加对CellStats.dll
文件的引用<ItemGroup>
标记。
查看上面列出的工程文件之一作为参考。
添加以下程序集依赖项:
MathWorks.MATLAB.Runtime.dll
MathWorks.MATLAB.Types.dll
将
CellStats.ctf
代码存档文件作为内容文件添加到工程中。在 Solution Explorer 中右键点击您的工程,然后选择 Add > Existing Item。在对话框中,浏览文件并添加文件。在 Solution Explorer 中右键点击
CellStats.ctf
文件并选择 Properties。在 Properties 窗口中,将 Build Action 设置为 Content,并将 Copy to Output Directory 设置为 Copy always。在 Solution Explorer 中右键点击您的工程并选择 Edit Project File。
CellConsoleApp.csproj
工程文件在编辑器中打开。添加<CopyToPublishDirectory>
标记正下方<CopyToOutputDirectory>
标记并将其设置为Always
。CellConsoleApp.csproj
工程文件的已编辑部分如下所示:... <ItemGroup> <Content Include="CellStats.ctf"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToPublishDirectory>Always</CopyToPublishDirectory> </Content> </ItemGroup> ...
在菜单栏上,选择 Build,然后选择 Build Solution 以在 Visual Studio 中构建应用程序。
编译过程会生成一个名为
CellConsoleApp.exe
的可执行文件。按 Ctrl+F5 从 Visual Studio 运行应用程序。或者,您可以从系统终端执行生成的可执行文件:
> cd C:\work\CellConsoleApp\CellConsoleApp\bin\Debug\net6.0 > CellConsoleApp.exe
应用程序会返回与 MATLAB 示例代码相同的输出。
INPUT temperatures [72.00, 75.00, 69.00, 68.00, 70.00] pressures [30.00, 29.50, 30.20, 29.90, 30.10] OUTPUT temperatures [72.00, 75.00, 69.00, 68.00, 70.00] 70.80 pressures [30.00, 29.50, 30.20, 29.90, 30.10] 29.94
提示
如果您无法构建应用程序,请将解决方案平台从
Any CPU
更改为x64
。如果您无法从 Visual Studio 运行应用程序,请打开 Developer Command Prompt for Visual Studio,然后输入
devenv /useenv
启动 Visual Studio。然后,打开您的工程并运行您的应用程序。
另请参阅
compiler.build.dotNETAssembly
| compiler.build.DotNETAssemblyOptions
| MathWorks.MATLAB.Types.RunOptions
主题
- 使用 MATLAB Data API for .NET 将 MATLAB 函数部署到 .NET 应用程序
- 使用 MATLAB Data API for .NET 将 MATLAB 类部署到 .NET 应用程序
- 将接受结构体数组作为输入参量的 MATLAB 函数部署到 .NET 应用程序
- MATLAB Compiler SDK .NET 目标要求
- 下载并安装 MATLAB Runtime
- Pass .NET Data Types to MATLAB Functions
- Handle MATLAB Data in .NET Applications