3
$\begingroup$

I have a program, written in C++, which uses WSTP to communicate with Mathematica 10 (i.e., linked using Install["name_program"]).

How should my code report an internal error? I've read through the WRI docs on Error and Interrupt Handling, but unfortunately they only talk about an instance where there are problems with the connection between the program and Mathematica, which doesn't apply to my case.

Example:

extern "C" int get_number(int param)
{
    try
    {
        //calculate result
        return result;
    }
    catch(...)
    {
        //What should be here?
    }
}
$\endgroup$
  • $\begingroup$ Since c does not use exceptions, WSTP does not, so the Try/Catch block is not useful, unless you are throwing your own errors. So, you put whatever you want. More specifically, each put/get function returns a bool (actually an int, but 0 is False, anything else is True) indicating if it has succeeded, and if it returns false, you handle it then. Your handling it could be Throw to a common error handler, but whether or not that is useful is for you to decide. $\endgroup$ – rcollyer Feb 16 '15 at 15:20
  • $\begingroup$ My suggestion is to report errors through return values, then have a Mathematica-side function that parses the return value and does what is necessary. For this, it's better to use the Manual return type in MathLink and return values explicitly. Then you'll have the option of returning e.g. $Failed (a symbol) or a number, or whatever expression you like. Generally: don't try to do too much in C, it's too much work. Make the C side as simple as you can and have a Mathematica side wrapper to handle more complex situations such as error reporting. $\endgroup$ – Szabolcs Feb 16 '15 at 15:21
4
$\begingroup$

tl; dr Report errors through return values. MathLink programs can return any Mathematica expression they like which makes structured error handling possible.


It looks like you have a function that returns integers with a template like

:Begin:
:Function:      get_number
:Pattern:       getNumber[x_Integer]
:Arguments:     {x}
:ArgumentTypes: {Integer32}
:ReturnType:    Integer32
:End:

Use a Manual return type instead:

:Begin:
:Function:      get_number
:Pattern:       getNumber[x_Integer]
:Arguments:     {x}
:ArgumentTypes: {Integer32}
:ReturnType:    Manual
:End:

Then you can return any expression you like, not just integers:

void get_number(int param) {
    ...
    if (success)
        MLPutInteger32(stdlink, result);
    else
        MLPutSymbol(stdlink, "$Failed");
}

You can return a symbol such as $Failed or a compound expression with some information about the error, e.g. myPackage`myError[12, "this is an error"].

Then instead of exposing getNumber on the Mathematica side to the user, create a wrapper for it that will handle the return values with pattern matching and whatever is needed on errors, e.g. issue a Message.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.