动态调用 MATLAB 函数
要动态调用 MATLAB® 函数,请将函数名称指定为调用请求的方法的参数之一。您无需创建一个编译接口来模拟可部署存档的内容,也不必在可部署存档中的函数发生变化时更改您的客户端应用程序。
要动态调用 MATLAB 函数:
实例化一个
MWClient实例。使用客户端连接的
CreateComponentProxy()方法之一创建基于反射的代理对象。使用基于反射的代理的
Invoke()方法之一调用一个或多个函数。
创建基于反射的代理
基于反射的代理实现了 MWInvokable 接口并提供允许您直接调用作为可部署存档的一部分部署的任何 MATLAB 函数的方法。与基于接口的代理一样,基于反射的代理也是从 MWClient 对象创建的。MWClient 接口有两种创建基于反射的代理的方法:
MWInvokable CreateComponentProxy(URL archiveURL)创建一个使用标准 MATLAB 数据类型的代理。MWInvokable CreateComponentProxy(URL archiveURL, MWMarshallingRules marshallingRules)创建一个使用结构体的代理。
要创建基于反射的代理来调用本地计算机上托管的 myMagic 存档中的函数:
MWClient myClient = new MWHttpClient();
Uri archiveURL = new Uri("http://localhost:9910/myMagic");
MWInvokable myProxy = myClient.CreateComponentProxy(archiveURL);
使用动态代理调用 MATLAB 函数
动态代理有三种调用服务器上的函数的方法:
Object[] Invoke(string functionName, IList<Type> targetTypes, params Object[] inputs)调用一个返回多个值的函数。T Invoke<T>(string functionName, params Object[] inputs)调用返回单个值的函数。void Invoke(string functionName, params Object[] inputs)调用一个不返回任何值的函数。
所有方法都映射到 MATLAB 函数,如下所示:
第一个参量是函数名称
最后参量是函数输入
返回多个输出
MATLAB 函数 myLimits 返回两个值。
function [myMin,myMax] = myLimits(myRange) myMin = min(myRange); myMax = max(myRange); end
要从 .NET 客户端调用 myLimits,请使用采用目标类型列表的 Invoke() 方法:
double[] myRange = new double[]{2,5,7,100,0.5};
IList<Type> targetTypes =
new List<Type> { typeof(double), typeof(double) };
Object[] myLimits = myProxy.Invoke("myLimits", targetTypes, myRange);
double myMin = myLimits[0];
double myMax = myLimits[1];
Console.WriteLine("min: {0:f} max: {1:f}", myMin, myMax);
这种形式的 Invoke() 总是返回 Object[]。返回数组的内容是根据 targetType 的内容进行类型的。
返回单个输出
MATLAB 函数 addmatrix 返回单个值。
function a = addmatrix(a1, a2)
a = a1 + a2;
要从 .NET 客户端调用 addmatrix,请使用不采用返回参量数量的 Invoke() 方法:
double[,] a1 = new double[,] {{1,2,3},{3,2,1}};
double[,] a2 = new double[,] {{4,5,6},{6,5,4}};
Object[] inputs = new Object[2];
inputs[0] = a1;
inputs[1] = a2;
double[,] result = myProxy.Invoke<double[,]>("addmatrix", inputs);
// display the result
无返回输出
MATLAB 函数 foo 没有返回值。
function foo(a1)
min(a1);
要从 .NET 客户端调用 foo,请使用返回 void 的 Invoke() 方法:
double[,] a = new double [,] {{1,2,3},{3,2,1}};
myProxy.Invoke("foo", a);
创建自定义封送规则
如果出现以下情况,您需要向基于反射的代理提供自定义编组规则:
可部署存档中的任何 MATLAB 函数都使用结构
可部署存档中的任何 MATLAB 都需要对默认编组规则进行自定义设置。
有默认规则编组
NaN、DateTime、.NET null、1xN 向量和 Nx1 向量。
向代理提供编组规则:
通过扩展
MWDefaultMarshalingRules来实现一组新的编组规则以覆盖默认值。使用
CreateComponentProxy(URL archiveURL, MWMarshallingRules marshalingRules)创建代理。
可部署存档 studentCheck 包含使用以下形式的 MATLAB 结构体的函数
S = name: 'Ed Plum' score: 83 grade: 'B+'
客户端代码用名为 Student 的类来表示 MATLAB 结构体。若要创建用于动态调用 studentChecker 中的函数的编组规则,请创建一个名为 studentMarshaller 的类。
class studentMarshaler : MWDefaultMarshalingRules
{
public override IList<Type> StructTypes()
{
get { return new List<Type> { typeof(Student) }; }
}
}
通过将 studentCheck 传递给 studentMarshaller 来为 createComponentProxy() 创建动态代理。
URL archiveURL = new URL("http://localhost:9910/studentCheck");
myProxy = myClient.CreateComponentProxy(archiveURL,
new StudentMarshaler());
有关使用 MATLAB 结构体的更多信息,请参阅 C# 中的 Marshal MATLAB 结构 (structs)。
有关其他数据编组规则的更多信息,请参阅 使用 C# 和 MATLAB 类型进行数据转换。