How to interrupt function m of MATLAB file from C / C ++?

I have deployed a MATLAB project to a DLL that is called from C ++ and it works fine. Happy Days.

But what happens when the user asks to cancel the operation?

I tried to create a variable global

named UserAborted

. I initialize it to 0 before running the long function in MATLAB. I also wrote the following two functions:

function AbortIfUserRequested
    global UserAborted

    if (UserAborted == 1)
        error('User Abort');
    end
end

function UserAbortLongFunction
    global UserAborted

    UserAborted = 1;
end

      

I call AbortIfUserRequested

on each iteration of the loop in my long function. I also exported UserAbortLongFunction

.

I expected that pretty soon after the call, the UserAbortLongFunction

long function would reach the call AbortIfUserRequested

and throw an error.

Instead, the long function continues to run until the end, and only then does the value change UserAborted

.

All I want to do is cancel this long function when the user asks me to! Is there a way to do this?

+2


source to share


3 answers


Matlab should provide callback functions to show the progress and possibly stop it. There are many people looking for this on google search, but not the implementation from Mathworks.



+1


source


Try calling the DRAWNOW function in AbortIfUserRequested. Although Matlab is single threaded (from an API point of view), it is interruptable. I had success calling this function with pure M code where user input (like Ctrl-C) would otherwise block.



+5


source


The single-threaded nature of Matlab can prevent the value of a global variable from propagating when passing through the first function. You can try sticking to the abort flag in a Java object like HashMap for the indirection layer. Since Java objects are passed by reference, an update to its state can be immediately displayed without requiring the Matlab variable itself to be changed.

Here is a snippet to do this. (Sorry, I don't have a Matlab Compiler license to check this in a deployed DLL.)

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 application data is also efficiently passed by reference. It might also add the abort flag to appdata instead of a global variable. If your library works with Matlab GUI, you can put application data on your shape descriptor instead of global descriptor 0. This will be more idiomatic Matlab than Java object if it works.

function AbortIfUserRequested
   if getappdata(0, 'UserAborted')
      error('User Abort');
   end
end
function UserAbortLongFunction
   setappdata(0, 'UserAborted', 1);
end

      

+1


source







All Articles