主要内容

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

动态调用 MATLAB 函数

要动态调用 MATLAB® Production Server™ 实例上的函数,可以使用基于反射的代理来构造 MATLAB 函数请求。函数名称和所有输入和输出都作为参数传递给调用请求的方法。这意味着您不需要每次向已部署的存档添加功能时都重新编译应用程序。

要动态调用 MATLAB 函数:

  1. 实例化 MWHttpClient 类的实例。

  2. 使用客户端连接的 createComponentProxy() 方法之一创建基于反射的代理对象。

  3. 使用基于反射的代理的 invoke() 方法之一调用该函数。

创建动态调用的代理

基于反射的代理实现了 MWInvokable 接口并提供了使您能够直接调用可部署存档中的任何 MATLAB 函数的方法。与基于接口的代理一样,基于反射的代理是从客户端连接对象创建的。MWHttpClient 类有两种创建基于反射的代理的方法:

  • MWInvokable createComponentProxy(URL archiveURL) 创建一个使用标准 MATLAB 数据类型的代理。

  • MWInvokable createComponentProxy(URL archiveURL, MWMarshalingRules marshalingRules) 创建一个使用结构体的代理。

要创建基于反射的代理来调用本地计算机上托管的存档 myMagic 中的函数:

MWClient myClient = new MWHttpClient();

URL archiveURL = new URL("http://localhost:9910/myMagic");
MWInvokable myProxy =  myClient.createComponentProxy(archiveURL);

动态调用 MATLAB 函数

基于反射的代理有三种调用服务器上的函数的方法:

  • Object[] invoke(final String functionName, final int nargout, final Class<T> targetType, final Object... inputs) 调用一个返回 nargout 值的函数。

  • <T> T invoke(final String functionName, final Class<T> targetType, final Object... inputs) 调用返回单个值的函数。

  • invokeVoid(final String functionName, final Object... inputs) 调用一个不返回任何值的函数。

所有方法映射到 MATLAB 函数如下:

  • 第一个参量是函数名称

  • 中间一组参量 nargouttargetType 表示函数的返回值

  • 最后参量是函数输入

返回多个输出

MATLAB 函数 myLimits 返回两个值。

function [myMin,myMax] = myLimits(myRange)
 myMin = min(myRange);
 myMax = max(myRange);
end

要从 Java® 客户端调用 myLimits,请使用采用多个返回参量的 invoke() 方法:

double[] myRange = new double[]{2,5,7,100,0.5};
try
{
  Object[] myLimits = myProxy.invoke("myLimits",
                                     2,
                                     Object[].class, 
                                     myRange);
  double myMin = ((Double) myLimits[0]).doubleValue(); 
  double myMax = ((Double) myLimits[1]).doubleValue();
  System.out.printf("min: %f max: %f",myMin,myMax);
}
catch (Throwable e)
{
  e.printStackTrace();
}

因为 Java 无法确定每个返回值的正确类型,所以 invoke 这种形式总是返回 Object[] 并且总是将 Object[].class 作为目标类型。您必须将返回的值转换为正确的类型。

返回单个输出

MATLAB 函数 addmatrix 返回单个值。

function a = addmatrix(a1, a2)
a = a1 + a2;

要从 Java 客户端调用 addmatrix,请使用不采用返回参量数量的 invoke() 方法:

double[][] a1={{1,2,3},{3,2,1}};
double[][] a2={{4,5,6},{6,5,4}};
try
{
  Double[][] result = myProxy.invoke("addmatrix", 
                                     Double[][].class, 
                                     a1, 
                                     a2);

  for(Double[] row : result)
  {
    for(double element : row)
    {
      System.out.print(element + " ");
    }
  }
} catch (Throwable e)
{
  e.printStackTrace();
}

无返回输出

MATLAB 函数 foo 没有返回值。

function foo(a1)
min(a1);

要从 Java 客户端调用 foo,请使用 invokeVoid() 方法:

double[][] a={{1,2,3},{3,2,1}};
try
{
  myProxy.invokeVoid("foo", (Object)a);
}
catch (Throwable e)
{
  e.printStackTrace();
}

MATLAB 结构体编组

如果可部署存档中的任何 MATLAB 函数使用结构体,则需要向基于反射的代理提供编组规则。向代理提供编组规则:

  1. 通过扩展 MWDefaultMarshalingRules 接口来使用被编组的类列表,从而实现一组新的编组规则。

  2. 使用 createComponentProxy(URL archiveURL, MWMarshalingRules marshalingRules) 方法创建代理。

可部署存档 studentChecker 包含使用以下形式的 MATLAB 结构体的函数

S = 
name: 'Ed Plum'
score: 83
grade: 'B+'

Java 客户端代码用名为 Student 的类来表示 MATLAB 结构体。若要创建用于动态调用 studentChecker 中的函数的编组规则,请创建一个名为 studentMarshaler 的类。

class studentMarshaler extends MWDefaultMarshalingRules
{
  public List<Class> getStructTypes() {
    List structType = new ArrayList<Class>();
    structType.add(Student.class);
    return structType;
  }
}

通过将 studentChecker 传递给 studentMarshaler 来为 createComponentProxy() 创建代理。

URL archiveURL = new URL("http://localhost:9910/studentCheck");
myProxy =  myClient.createComponentProxy(archiveURL,
                                         new StudentMarshaler());

有关使用 MATLAB 结构体的更多信息,请参阅 在 MATLAB 中编组 Java 结构 (Structs)