Loren on the Art of MATLAB

September 17th, 2008

Managing Non-Deployable Functions in a Compiled Application

Guest blogger Peter Webb presents another post about building applications with the MATLAB Compiler. This week's topic: understanding the types of functions that cannot be deployed and managing those that behave differently when deployed.

For an introduction to writing deployable code, please see the June 19th post.

Contents

When you're writing an application you intend to deploy with the MATLAB Compiler, you need to be aware that a subset of MATLAB's functions either cannot be deployed or behave differently when deployed.

There are two classes of non-deployable functions: functions that are not licensed for deployment; and functions that the deployment runtime (the MATLAB Common Runtime or MCR) cannot support.

Excluded Functions: Design Time Functions and GUIs

The intent of the MATLAB Compiler and the Builders is to create a robust application with predictable behavior. In part, this means that the users of the deployed application should not be able to modify it. Preventing users from modifying deployed applications has several benefits:

  • Predictable performance and results: The application will always work just as it did when it was deployed.
  • Easier to support: The support organization does not have to cope with user-introduced bugs.
  • Protection of intellectual property: Making the code unreadable (and hence, unmodifiable) means users cannot copy the algorithms.
  • Increased security: An application distributed in binary, encrypted form is more tamper-resistant than one for which the source code is available.

To prevent the modification of deployed applications, the Compiler includes only those M-files the application actually uses, encrypts the M-files (this also protects the intellectual property they contain), creates MEX authorization files, and truncates the MATLAB path. But editing M-files and modifying the MATLAB path is not the only way to change a MATLAB application. Certain MATLAB and toolbox functions can themselves change an application's behavior. For example, the MATLAB debugger can interactively modify the contents of variables and change the order in which the interpreter calls functions. Similarly, the figure property editor can modify figure callback strings. The Compiler prevents these types of modifications by refusing to compile the functions that perform them; these functions are excluded from the generated CTF archive.

In general the Compiler excludes those functions used when developing an application. Most of these design time functions fall into one of two categories: those that permit the application to change the way it works, like dbstop and propedit; and those that are complete mini-applications in and of themselves, like imtool and guide. This includes, but is not limited to:

  • All types of debugging functions.
  • Most of the toolbox functions ending in tool, such as imtool and sptool.
  • Functions that generate or edit M-code directly or indirectly; this includes, for example, the Neural Network Toolbox network training functions such as train.

Many of these restrictions have no workaround: debugging functions and functions which generate M-code simply cannot be deployed. There's no workaround for the debugging functions because they are builtins, and there's no effective way to debug MATLAB code using M-files. Functions which generate M-code will not work in a deployed application because they have no way of encrypting the generated M-code, which the MCR requires. You can, of course, write your own code to compensate for other types of excluded functions, but keep in mind that cloning MATLAB or toolbox functions violates your license agreement, which we don't encourage.

The Compiler creates a list of excluded functions in the output directory. This list, mccExcludedFiles.log, which is often quite long, contains the full paths to the M-files that the Compiler removed from the list produced by depfun and a short explanation for why each function cannot be deployed.

We publish a list of deployable functions; this list may change with each release of MATLAB and the deployable toolboxes.

Unsupported Functions: Differences in the Execution Environment

Certain MATLAB functions cannot be deployed because they act on objects that are not present in a deployed application. For example, since deployed applications have no command window, functions that modify the command window can't be deployed.

Use of these functions in deployed application will result in mlint warnings in the MATLAB editor and runtime warnings in the deployed application. For example, calls to help generate this text when deployed:

Warning: The HELP function cannot be used in compiled applications.

You can prevent your deployed applications from displaying warnings like this via the isdeployed function. For more details, see the previous blog posting about path management in deployed applications.

There are currently four non-deployable MATLAB functions:

  • help: Deployed applications typically do not include MATLAB or toolbox help files, so there's no need for a help function.
  • helpwin: helpwin displays help text in a new window; like help it is of very little use in deployed applications because deployed applications do not contain MATLAB's help files.
  • keyboard: Since a deployed component may be part of a graphical application with no keyboard input stream, the MATLAB Compiler does not not support deployment of the keyboard function.
  • savepath: A deployed application's path is fixed and unchangeable, which means there's no need to save the path.

The versions of these functions that issue warnings override the versions in MATLAB because of their location in toolbox/compiler/deploy which always appears first on the path used by mcc and depfun.

Functions that Work Differently

Where the differences between MATLAB and the deployed environment are not insurmountable, the MATLAB Compiler and the Builder tools offer versions of MATLAB functions that have been modified to work in deployed applications.

Eight important MATLAB functions work differently in deployed applications:

  • clc: In MATLAB, clc clears the command window. Since deployed applications do not display a command window, clc clears the shell or DOS window in which the application was started.
  • fopen: In a deployed application, fopen looks for the specified file in the unpacked CTF archive before looking for it in the current directory. This means that fopen will preferentially open files shipped with application, even if there's a file in the current directory with the same name. Note that preferring files contained in the CTF archive is most often exactly what you want the deployed fopen to do. Please don't be tempted to use a full path to work around this behavior as that may create further problems when the application is deployed. For more details on why, see the previous blog posting in this series.
  • home: In MATLAB, home returns the prompt to the upper left of the command window. In a deployed application, it moves the prompt to the upper left of the shell or DOS window from which the application was started. Unlike clc, home does not clear the existing text in the window.
  • input: The deployed version of input reads from the shell or DOS command window instead of the MATLAB command window. If there is no command window available, input will hang or fail.
  • loadlibrary: The version of loadlibrary which operates on C-style header interfaces is not available in deployed applications; but the Compiler does support loadlibrary with M-file prototypes.
  • pause: Like input, pause (without a timeout argument) reads from the shell or DOS command window in a deployed application. If no such window is available pause will pause forever.
  • print: A full accounting of the differences between printing in a deployed application and printing in MATLAB is beyond the scope of this posting. While you can still use print for generating bitmaps or JPEGs from your figures, for hardcopy you must use deployprint instead. For example:
        if isdeployed
            deployprint
        else
            print
        end
  • printdlg: Deployed applications only support the single argument version of printdlg, i.e., printdlg(fig).

You'll find the code for the deployment-specific versions of these functions in toolbox/compiler/deploy. You can control if these functions get called in deployed applications using the isdeployed function. In the unlikely event that you need to change how these functions work, you can overload them by creating a function of the same name in your top-level application directory. The Compiler will set the path of the generated application so that your M-file gets called instead of the one in toolbox/compiler/deploy.

Finally, please note that functions deployed as the main routine of a standalone executable may need to process their input arguments differently when deployed. When making a standalone executable from a MATLAB function that takes parameters, the MATLAB Compiler generates code to pass any user-supplied command line arguments to the compiled MATLAB function. However, the command line arguments are passed to the MATLAB function as strings, even if they are numeric. Therefore, any M-function serving as the entry point for a compiled MATLAB program should expect (or at least test for) string input. For example:

 function y = addten(x)
   if isstr(x)
       x = str2num(x);
   end
   y = x + 10;

Deploying Your Applications

Deploying your applications will be easier if you follow these guidelines:

  • Use isdeployed to protect non-deployable code from being called by deployed applications.
  • Remember that a deployed application has no MATLAB command window (or any of the other desktop tools, like the editor).
  • Don't change the path or rely on the current directory; deployed applications are supposed to be less flexible than MATLAB applications (this makes them more secure and easier to support).

Most of the information in this series of postings will eventually end up in the documentation for the MATLAB Compiler. Please comment on anything you feel was unclear, and ask any questions you think were unanswered. And feel free to contact me if you have other questions about the MATLAB Compiler or the Builders or post your thoughts here.


Get the MATLAB code

Published with MATLAB® 7.6

8 Responses to “Managing Non-Deployable Functions in a Compiled Application”

  1. Martin V replied on :

    Hi,

    Is there a way to prevent the whole standalone application (generated with mcc -m) to crash when a single error occurs? I have a large GUI program with lots of callbacks. If one of the users of my program does something unintended causing an error in a callback function I would like the GUI program to continue running, like it does in a normal MATLAB session, and not crash the program. Is there a smart way to solve this problem other than by a lot of try-catching?

    Best regards,
    Martin

  2. wobbly replied on :

    I have frequently missed a global “onerror” function such as VB has.

    It is a big problem that an error causes a crash, and the console disappears without any error messages being visible to the users.
    OnError would allow the error message to be at least displayed in a dialog before exiting.

  3. OkinawaDolphin replied on :

    Some questions about printing figures in deployed programs:

    1. When I write printdlg(handles.NameOfThisFigure) in a callback function, there is a warning stating that MCC does not permit printdlg. My Matlab version is R2007a. Has printdlg() been deployable in more recent versions?

    2. In Matlab I can print figures as PDF files. In deployed applications this option is still offered, but I always get an error when trying to do this. Is there any other way of exporting figures to PDF files without purchasing the Report Generator first?

    About neural networks: I do not fully understand why training a neural network requires generating M code. Is there no possibility to develop a training function that just generates the data, e. g. a cell array or struct of weight vectors?

    The Neural Network Toolbox is useless for anyone who wants to deploy his or her programs. It is possible that a developper of a program retrains a network if necessary. However, this is not necessarily a developer’s job. The user of a program can do this, too - maybe better than a developper who is a specialist in pattern recognition, but not in the application domain (e. g. surface inspection, medical diagnosis, measurement and control).

  4. Peter Webb replied on :

    Martin and wobbly,

    Try-catch is really the best way to manage errors in a deployed application. Having a global OnError function causes problems when you’ve got more than one compiled component linked into the same application — if multiple components report an error, which should the function report?

    However, each compiled component can control how its own error messages are displayed or logged by registering an error output function. See the online documentation for more details:

    http://www.mathworks.com/access/helpdesk/help/toolbox/compiler/f2-998954.html

    (Click on the “Print and Error Handling Functions” link.)

  5. Peter Webb replied on :

    OkinawaDolphin,

    1. printdlg works in deployed applications, at least as of roughly 2006. Note that deployed applications only support the single argument form of printdlg, i.e., printdlg(figure_handle).

    2. In deployed applications you cannot print PDFs via deployprint (either interactively or not), but you should be able to create PDFs by calling print -dpdf directly.

    3. Regarding Neural Networks, the use of generated MATLAB functions is a core part of the toolbox’s functionality; until that changes, the deployability of Neural Networks will be limited, as detailed here:

    http://www.mathworks.com/products/compiler/compiler_support.html

  6. OkinawaDolphin replied on :

    Peter Webb,

    my question is about creating PDFs using deployed applications.

    When trying to use printdlg, MLint says “MCC does not permit the PRINTDLG function”. Indeed I get a strange error message when calling it in a deployed program. According to MLint, print is not permitted either.

    It seems it is impossible to create PDFs from deployed applications. Trying to print the figure clicking the printer symbol and choosing the PDF printer works, but the results are not satisfactory.

    Is there any reason for not permitting the creation of PDFs from deployed applications or is M code generated during creating a PDF?

  7. Ofra replied on :

    Is there any light version of plotedit or plottolls that can be compiled with standalone application.
    I need to give the user the option to control the following properties of a figure: title, xlabel, ylabel, axis, line colors in the plotted graph.

  8. Michele Squillante replied on :

    I’ve tried to modify some Matlab built-in functions (specifically some of the built-in dialog boxes, like errordlg or warndlg) and then use them in a compiled application. Seems like the modifications are not effective in the compiled software. Is there any way to work around this issue?

    Thank you very much

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Jun: I totally can not believe it, Loren. You are really helpful. Thank you so much, MATLAB master!
  • Loren: Wow folks- Always lots of interest when there’s a quickie to try out! I will only make 2 general...
  • Loren: Jun- ismember is your friend here: >> [aa,ind] = ismember(Array2,Arra y1) aa = 1 1 1 1 1 1 1 ind = 1 2 1 4 4 3...
  • Dan: I like the first way better than the second way. Combining the arrays into one and running any is nice, although...
  • James Myatt: How about I = (a == 0 | b == 0); a(I) = []; b(I) = [];
  • Tunc: Hello Loren, love your blog because of such inspiring and challenging comments to such ’small’...
  • Pekka Kumpulainen: Here is my tradeoff. I usually want to keep the original variables as they are most probably...
  • Iain: Followup: Of course, to allow NaNs (counting them as non-zero): mask = (a~=0) & (b~=0); The mask says “a...
  • Matt Fig: I would usually go with something like this: y = a&b; x = a(y); y = b(y); But I was surprised to find...
  • kk: c=all([a;b]) a(c) a(b)

These postings are the author's and don't necessarily represent the opinions of The MathWorks.