从F#调用Matlab的MLApp.MLAppClass.FEval

时间:2010-05-13 05:55:09

标签: com matlab f# variant comexception

Matlab提供了一个COM接口,支持远程执行任意函数(和代码片段)。特别是,它有一个调用给定Matlab函数的Feval方法。此方法的第三个参数pvarArgOut具有COM类型VARIANT *,并在Visual Studio F#编辑器中显示为类型的参数:

pvarArgOut: byref<obj>

以下代码调用interp1,它在Matlab中返回一个矩阵(即2D双数组)结果,这对于大多数Matlab函数来说都是正常的。

let matlab = new MLApp.MLAppClass()

let vector_to_array2d (v : vector) = Array2D.init v.Length 1 (fun i j -> v.[i])

let interp1 (xs : vector) (ys : vector) (xi : vector) =
    let yi : obj = new obj()
    matlab.Feval("interp1", 1, ref yi, vector_to_array2d xs, vector_to_array2d ys, vector_to_array2d xi)
    yi :?> float[,]

这段代码编译得很好,但是当调用interp1时,我得到一个COM异常:

A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll

Additional information: Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))

无论是使用新的obj,新的Array2D还是null来初始化yi,我都会遇到同样的错误。

F#如何翻译VARIANT输出参数?

更新

以下是更正后的版本:

let matlab = new MLApp.MLAppClass()

let vector_to_array2d (v : vector) = Array2D.init v.Length 1 (fun i j -> v.[i])

let interp1 (xs : vector) (ys : vector) (xi : vector) =
    let mutable oi : obj = null
    matlab.Feval("interp1", 1, &oi, vector_to_array2d xs, vector_to_array2d ys, vector_to_array2d xi)
    (oi :?> obj[]).[0] :?> float[,]

2 个答案:

答案 0 :(得分:1)

StrangeLights.com上的文章F Sharp And MATLAB描述了使用F#v1.1.5和F#PowerPack中的MATLAB。

缺少的步骤是使用tlbimp创建互操作性dll,例如

tlbimp“c:\ Program Files \ MATLAB \ R2006a \ bin \ win32 \ mlapp.tlb”

然后在F#中使用

导入此dll

'#r“Interop.MLApp.dll”'

答案 1 :(得分:1)

您不希望ref yi

let mutable yi = new obj()
thatfunc(..., &yi, ...)

虽然我认为仅靠这一点无法解决问题。 Perchance是否有调用此特定API的C#示例?