1

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[,]
4

2 回答 2

1

StrangeLights.com 上的文章F Sharp 和 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"'

于 2010-05-13T07:31:40.820 回答
1

你不想要ref yi,你想要

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

尽管我认为仅凭这一点并不能解决问题。是否有调用此特定 API 的 C# 示例?

于 2010-05-13T12:31:46.073 回答