Comment puis-je annuler une fonction m-file Matlab de C / C ++?
Question
Je déployé un projet Matlab dans une DLL, d'être appelé à partir de C ++, et il fonctionne très bien. jours heureux.
Mais ce qui se passe lorsque l'utilisateur demande d'annuler une opération?
J'ai essayé de créer une variable global
nommée UserAborted
. J'initialiser à 0 avant d'exécuter la longue fonction dans MATLAB. J'ai écrit aussi les deux fonctions suivantes:
function AbortIfUserRequested
global UserAborted
if (UserAborted == 1)
error('User Abort');
end
end
function UserAbortLongFunction
global UserAborted
UserAborted = 1;
end
Je demande à AbortIfUserRequested
à chaque itération de la boucle dans ma longue fonction. J'ai aussi exporté UserAbortLongFunction
.
Je m'y attendais assez peu de temps après appelé UserAbortLongFunction
, la longue fonction atteindrait un appel à AbortIfUserRequested
, et une erreur.
Au lieu de cela, la fonction de temps continue à fonctionner jusqu'à la fin, et seulement puis ne la valeur de UserAborted
se changer.
Tout ce que je veux faire est abort cette fonction longtemps lorsque l'utilisateur me demande! Est-il possible de le faire?
La solution
Matlab doit fournir des fonctions de rappel pour montrer les progrès d'exécution et peut-être mettre fin. Une recherche sur Google montre beaucoup de gens qui veulent cela, mais pas la mise en œuvre de Mathworks.
Autres conseils
Essayez d'appeler la fonction drawNow dans AbortIfUserRequested. Bien que Matlab est mono-thread (du point de vue de l'API), il ne permet d'interruptions. J'ai eu du succès en appelant cette fonction avec M-pur code où l'entrée d'utilisateur (comme Ctrl-C) se autrement en lock-out.
nature mono-thread Matlab peut empêcher le mise à jour à la valeur de la variable globale de se propager alors que la première fonction est en cours d'exécution. Vous pouvez essayer de coller le drapeau abort dans un objet Java, comme une table de hachage, pour une couche d'indirection. Étant donné que les objets Java sont passés par référence, une mise à jour à son état peut être visible immédiatement, sans nécessiter un changement à la variable Matlab lui-même.
Voici un extrait de le faire. (Désolé, je n'ai pas de licence compilateur Matlab pour tester ceci dans une DLL déployée.)
function AbortIfUserRequested
global SharedState
if SharedState.get('UserAborted')
error('User Abort');
end
end
function UserAbortLongFunction
global SharedState
SharedState.put('UserAborted', 1);
end
function InitUserAbort
global SharedState
SharedState = java.util.Collections.synchronizedMap(java.util.HashMap());
SharedState.put('UserAborted', 0);
end
Matlab données app est également efficace passé par référence. Mettre le drapeau abort dans AppData au lieu d'une variable globale pourrait fonctionner aussi. Si votre bibliothèque fonctionne avec une interface graphique Matlab, vous pouvez mettre les données d'application sur la poignée de la figure à la place de la poignée globale 0. Ce serait plus idiomatiques Matlab que l'objet Java, si cela fonctionne.
function AbortIfUserRequested
if getappdata(0, 'UserAborted')
error('User Abort');
end
end
function UserAbortLongFunction
setappdata(0, 'UserAborted', 1);
end