2010-05-13 4 views
1

Matlab fournit une interface COM prenant en charge l'exécution à distance de fonctions arbitraires (et d'extraits de code). En particulier, il a une méthode Feval qui appelle une fonction Matlab donnée. Le troisième paramètre à cette méthode, pvarArgOut, est de type COM VARIANT *, et apparaît dans l'éditeur Visual Studio F # comme un argument de type:Appel de MLApp.MLAppClass.FEval de Matlab à partir de F #

pvarArgOut: byref<obj> 

Le code suivant appelle interp1, qui Matlab renvoie une matrice (c.-à- Résultat du double tableau 2D), comme d'habitude pour la plupart des fonctions 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[,] 

Ce code compile très bien, mais lorsque vous appelez interp1, je reçois une exception 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)) 

je reçois la même erreur si initialize yi avec une nouvelle obj, une nouvelle Array2D ou nulle.

Comment F # traduit-il les arguments de sortie VARIANT?

Mise à jour

Voici la version corrigée:

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

Répondre

1

vous ne voulez pas ref yi, vous voulez

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

bien que je pense que seul ne le résoudra pas. Est-ce qu'il y a un exemple d'appel de cette API particulière?

+0

Cela fonctionne! - avec une petite modification pour initialiser yi à null plutôt qu'un nouvel obj(). Après l'appel, la variable yi contient un tableau d'objets avec le premier élément défini sur un double tableau bidimensionnel. Parfait. Merci Brian! – Matthew

+0

Salut Matthew, pourriez-vous s'il vous plaît ajouter un exemple de travail? Merci d'avance. –

1

L'article F Sharp And MATLAB sur StrangeLights.com décrit l'utilisation de F # Matlab v1.1.5 et F # PowerPack.

L'étape manquante est de créer une dll d'interopérabilité en utilisant tlbimp par exemple

tlbimp "c: \ Program Files \ Matlab \ R2006a \ bin \ win32 \ mlapp.tlb"

alors dans les F #import ce dll avec

'#R "Interop.MLApp.dll"'

+0

Merci Matt; J'avais vu l'article - c'est un bon article, et ça m'a permis de démarrer, mais ça ne couvre pas l'utilisation de Feval. J'ai déjà créé la DLL d'interopérabilité et l'ai ajoutée comme référence de projet, donc ça ne peut pas être ... – Matthew

+0

Oups, désolé de penser que c'était aussi simple. Je viens juste de jeter un coup d'œil et de reproduire le comportement mais je n'ai pas trouvé de solution. –