2011-09-19 4 views
3

J'essaye d'écrire une fonction C++ mex pour Matlab qui peut gérer plusieurs types de données. Matlab me donne un mxArray*, à partir de laquelle je peux récupérer un void* pour les données, et un mxClassID me disant le type de données. Donc, je peux faire quelque chose comme:C++ décode bien le pointeur vide pour Matlab mex

void *data = mxGetData(mxarray); 
switch (mxGetClassID(mxarray)) { 
    case mxDOUBLE_CLASS: 
    my_function(static_cast<double *>(data)); 
    ... 

my_function est basé sur un modèle, donc ce poignées différentes types de données bien. Mais il est toujours très ennuyeux d'avoir besoin de ce commutateur pour tous les my_function1, my_function2

Jusqu'ici, la solution que j'ai trouvée est d'utiliser une approche fonctionnelle et d'avoir une méthode qui accepte un foncteur:

template <typename ReturnType, typename FunctorType> 
ReturnType mxarr_apply(const mxArray *inarr, FunctorType functor) { 
    void *data = mxGetData(inarr); 
    switch (mxGetClassID(inarr)) { 
    case mxDOUBLE_CLASS: 
     return (ReturnType) functor(static_cast<double *>(data)); 
    ... 

de cette façon, je peux mettre ma logique dans le foncteur (avec operator() templated) et ne pas avoir à recréer le basculement et plus. Mais je me demande s'il existe d'autres moyens? En Java, je pense que je pourrais juste avoir une fonction qui convertit le mxClassID directement en une référence class qui pourrait ensuite être utilisée pour instancier un type de manière flexible à l'exécution, mais cela ne semble pas être une option en C++.

Répondre

2

Vous avez raison. Il n'y a aucun moyen en C++ pour obtenir une référence de classe à l'exécution. Vous devez écrire l'interrupteur, au moins une fois.

+1

+1 .. et de préférence au maximum une fois – stijn

+0

Merci beaucoup. Et pour écrire le commutateur une seule fois, l'approche du foncteur est la voie à suivre? Ou y a-t-il d'autres options? Cette configuration devient particulièrement pénible lorsqu'il s'agit de sortie. Je trouve que je suis limité à la production basée sur les effets secondaires pour de nombreuses situations. – Chinasaur

0

Si vous faites face à la nécessité d'écrire plusieurs commutateurs vous voudrez peut-être l'obligation de cacher c'est logique dans une usine, qui renverrait le foncteur droit étant donné le type

void *data = mxGetData(mxarray); 
functor func = FunctorFactory::Get(mxGetClassID(mxarray)); 
func (reinterpret_cast<double*>(data)); 

ou simplement créer une carte (de préférence non ordonnée ou un hachage) des types aux foncteurs.

void *data = mxGetData(mxarray); 
functor func = functorMap[mxGetClassID(mxarray)]; // need to check for key availability 
func (reinterpret_cast<double*>(data)); 
+0

Merci, des suggestions intéressantes. Pour le modèle d'usine de foncteurs, les types de retour du foncteur seraient corrigés, n'est-ce pas? Je fais mes foncteurs avec le modèle 'operator()', de sorte que généralement gère le droit par type. – Chinasaur

+0

Je pense que static_cast est correct pour cette situation; J'ai changé mes exemples de C-style à static_cast. – Chinasaur

Questions connexes