Matlab предоставляет интерфейс COM, который поддерживает удаленное выполнение произвольных функций (и фрагментов кода). В частности, он имеет метод Feval, который вызывает данную функцию Matlab. Третий параметр этого метода, pvarArgOut, имеет тип COM VARIANT * и отображается в редакторе Visual Studio F # в качестве аргумента типа:
pvarArgOut: byref<obj>
Следующий код вызывает interp1, который в Matlab возвращает результат матрицы (то есть двумерный двойной массив), как обычно для большинства функций 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))
Я получаю ту же ошибку при инициализации yi с новым obj, новым Array2D или null.
Как 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[,]