主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

使用原生 .NET API 访问可远程访问的 .NET 程序集:元胞与结构体

为什么要将 .NET API 与元胞数组和结构体一起使用?

如果满足以下两个条件,则建议使用 MATLAB® 结构和元胞数组的 .NET 表示形式:

  • 您在服务器上拥有 MATLAB 函数,并以 MATLAB 结构或单元数据类型作为输入或输出

  • 您不想或不需要在客户端计算机上安装 MATLAB Runtime

本机 MWArrayMWStructArrayMWCellArray 类是 MathWorks.MATLAB.NET.Arrays.native 命名空间的成员。

该命名空间中的类名与 MathWorks.MATLAB.NET.Arrays 中的类名相同。不同之处在于结构体和元胞数组的本机表示没有需要 MATLAB Runtime 的方法或属性。

matlabroot\toolbox\dotnetbuilder\Examples\VSVersion\NET 文件夹包含您可以练习构建的示例解决方案。NativeStructCellExample 文件夹包含本机结构和单元示例。

构建您的组件

此示例演示如何使用原生结构和元胞数组部署可远程组件。在设置远程客户端和服务器代码之前,请使用 创建可远程访问的 .NET 程序集 中的说明构建远程组件。

本机 .NET 元胞和结构体示例

服务器应用程序承载远程组件。

在单独的进程中运行的客户端应用程序访问由服务器应用程序托管的远程组件。使用 Microsoft® Visual Studio® 工程文件 NativeStructCellServer.csproj 构建服务器:

  1. 将生成的组件程序集的引用更改为 component_nameNative.dll

  2. 选择合适的构建平台。

  3. 选择 DebugRelease 模式。

  4. 构建 NativeStructCellServer 工程。

  5. 提供 NativeStructCellServer 的配置文件。服务器的 C# 代码位于文件 NativeStructCellServer.cs 中:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Remoting;
    
    namespace NativeStructCellServer
    {
      class NativeStructCellServer
         {
           static void Main(string[] args)
            {
               RemotingConfiguration.Configure(
                                 @"NativeStructCellServer.exe.config");
    
               Console.WriteLine("NativeStructCell Server started...");
    
               Console.ReadLine();
            }
         }
    }
    
    此代码读取相关的配置文件以确定:

    • 要托管的组件的名称

    • 要使用的远程协议和消息格式

    • 远程组件的租用时间

    此外,该代码还表示服务器处于活动状态,并等待回车符后再终止。

编码并构建客户端应用程序和配置文件

运行在单独进程中的客户端应用程序访问运行在内置服务器应用程序中的远程组件本机 .NET 元胞和结构体示例。使用 Microsoft Visual Studio 工程文件 NativeStructCellClient\NativeStructCellClient.csproj 构建远程客户端。要使用 Microsoft Visual Studio 创建远程客户端:

  1. 将生成的组件程序集的引用更改为 component_nameNative.dll

  2. 将生成的接口程序集的引用更改为 Icomponent_nameNative.dll

  3. 选择合适的构建平台。

  4. 选择 DebugRelease 模式。

  5. 构建 NativeStructCellClient 工程。

  6. 提供 NativeStructCellClient 的配置文件。

NativeStructCellClient 代码

客户端的 C# 代码位于文件 NativeStructCellClient\NativeStructCellClient.cs 中:

 NativeStructCellClient.cs

此代码执行以下操作:

  • 客户端读取相关的配置文件来获取远程组件的名称和位置。

  • 客户端使用静态 Activator.GetObject 方法实例化可远程访问对象

  • 从此时起,远程客户端调用可远程组件上的方法就像调用本地组件方法一样。

NativeStructCellClient 配置文件

NativeStructCellClient 的配置文件位于文件 NativeStructCellClient\NativeStructCellClient.exe.config 中:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="NativeStructCellServer" value=
              "tcp://localhost:1236/NativeStructCellClass.remote"/>    
  </appSettings>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel name="NativeStructCellChannel" ref="tcp" port="0">        
          <clientProviders>            
            <formatter ref="binary" />
          </clientProviders>
          <serverProviders>            
            <formatter ref="binary" typeFilterLevel="Full" />
          </serverProviders>            
        </channel>
      </channels>
    </application>
  </system.runtime.remoting>
</configuration>

本规范规定:

  • 远程组件服务器的名称和远程组件 URI(统一资源标识符)

  • 远程协议 (TCP/IP) 和端口号

  • 消息格式化程序 (binary) 和通信通道的权限(full 信任)

启动服务器应用程序

通过执行以下操作启动服务器:

  1. 打开 DOS 或 UNIX® 命令行窗口并导航到 NativeStructCellServer\bin\x86\v4.0\Debug

  2. 运行 NativeStructCellServer.exe。出现以下输出:

    EVENT 1: Initializing the structure on server and sending 
             it to client:
            Initialized empty structure:
    
          Name: ' '
       Address: []
    
    
    ##################################
    
    EVENT 3: Partially initialized structure as 
             received by server:
    
          Name: ' '
       Address: [1x1 struct]
    
    Address field as initialized from the client:
    
       Street: '3, Apple Hill Drive'
         City: 'Natick'
        State: 'MA'
          Zip: '01760'
    
    ##################################
    
    EVENT 4: Updating 'Name' field before sending the 
             structure back to the client:
    
          Name: 'The MathWorks'
       Address: [1x1 struct]
    
    
    ##################################
    

启动客户端应用程序

通过执行以下操作启动客户端:

  1. 打开 DOS 或 UNIX 命令行窗口并导航到 NativeStructCellClient\bin\x86\v4.0\Debug

  2. 运行 NativeStructCellClient.exeMATLAB Runtime 初始化后,出现以下输出:

    EVENT 2: Initialized structure as 
             received in client applications:
    
    1x1 struct array with fields:
           Name
           Address
    
    Updating the 'Address' field to :
    
    1x1 struct array with fields:
           Street
           City
           State
           Zip
    
    #################################
    
    
    EVENT 5: Final structure as received by client:
    
    1x1 struct array with fields:
           Name
           Address
    
    Address field:
    
    1x1 struct array with fields:
           Street
           City
           State
           Zip
    
    #################################
    

使用本机 MWArray、MWStructArray 和 MWCellArray 类编码和构建客户端应用程序和配置文件

createEmptyStruct.m

使用以下 MATLAB 代码在服务器上初始化结构并将其发送到客户端:

function PartialStruct = createEmptyStruct(field_names)

fprintf('EVENT 1: Initializing the structure on server 
                         and sending it to client:\n');

PartialStruct = struct(field_names{1},' ',field_names{2},[]);

fprintf('         Initialized empty structure:\n\n');
disp(PartialStruct);
fprintf('\n##################################\n');

updateField.m

使用以下 MATLAB 代码从客户端接收部分更新的结构并向其中添加更多数据,然后将其传回客户端:

function FinalStruct = updateField(st,field_name)

fprintf('\nEVENT 3: Partially initialized structure as 
                              received by server:\n\n');
disp(st);
fprintf('Address field as initialized from the client:\n\n');
disp(st.Address);
fprintf('##################################\n');

fprintf(['\nEVENT 4: Updating ''', field_name, ''' 
   field before sending the structure back to the client:\n\n']);
st.(field_name) = 'The MathWorks';
FinalStruct = st;
disp(FinalStruct);
fprintf('\n##################################\n');

NativeStructCellClient.cs

创建客户端 C# 代码:

注意

在这种情况下,您不需要系统路径上的 MATLAB Runtime

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Configuration;
using MathWorks.MATLAB.NET.Arrays.native;

using INativeStructCellCompNative;

// This is a simple example that demonstrates the use of 
//     MathWorks.MATLAB.NET.Arrays.native package. 
namespace NativeStructCellClient
{
    class NativeStructCellClient
    {
        static void Main(string[] args)
        {
            try
            {
                RemotingConfiguration.Configure
                      (@"NativeStructCellClient.exe.config");
                String urlServer =
                      ConfigurationSettings.AppSettings[
                                                     "NativeStructCellServer"];
                INativeStructCellClassNative nativeStructCell = 
                      (INativeStructCellClassNative)Activator.GetObject(typeof
                           (INativeStructCellClassNative), 
                           urlServer);

                MWCellArray field_names = new MWCellArray(1, 2);
                field_names[1, 1] = "Name";
                field_names[1, 2] = "Address"; 

                Object[] o = nativeStructCell.createEmptyStruct(1,field_names);
                MWStructArray S1 = (MWStructArray)o[0];
                Console.WriteLine("\nEVENT 2: Initialized structure as received 
                                     in client applications:\n\n{0}" , S1);

                //Convert "Name" value from char[,] to a string since 
                // there's no MWCharArray constructor 
                // on server that accepts char[,] as input.
                char c = ((char[,])S1["Name"])[0, 0];
                S1["Name"] = c.ToString();                

                MWStructArray address = 
                      want new MWStructArray(new int[] { 1, 1 }, 
                             new String[] { "Street", "City", "State", "Zip" });
                address["Street", 1] = "3, Apple Hill Drive";
                address["City",   1] = "Natick";
                address["State",  1] = "MA";
                address["Zip",    1] = "01760";

                Console.WriteLine("\nUpdating the 
                                   'Address' field to :\n\n{0}", address);
                Console.WriteLine("\n#################################\n");
                S1["Address",1] = address;

                Object[] o1 = nativeStructCell.updateField(1, S1, "Name");
                MWStructArray S2 = (MWStructArray)o1[0];

                Console.WriteLine("\nEVENT 5: Final structure as received by 
                                     client:\n\n{0}" , S2); 
                Console.WriteLine("\nAddress field: \n\n{0}" , S2["Address",1]);
                Console.WriteLine("\n#################################\n");
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
            }
            Console.ReadLine();
        }
    }
}

NativeStructCellServer.cs

创建服务器 C# 代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;

namespace NativeStructCellServer
{
    class NativeStructCellServer
    {
        static void Main(string[] args)
        {
            RemotingConfiguration.Configure(
                              @"NativeStructCellServer.exe.config");

            Console.WriteLine("NativeStructCell Server started...");

            Console.ReadLine();
        }
    }
}