0
$\begingroup$

I've successfully compiled the simple addtwo function predefined in Mathematica as per: MathLink dependencies: "LNK2019: unresolved external symbol _MLMain" I am now attempting to write an external function which calls a class I wrote earlier and returns a list of values using an output file called output.tm. The output file is as follows:

void output P((double, double, double, double, double, double, double, double, int, int));

:Begin:
:Function:       output
:Pattern:        output[x0_Real64, t0_Real64, tend_Real64, deltat_Real64, D_Real64, p_Real64, q_Real64, finallevel_Real64, nDIM_Integer32, iterations_Integer32]
:Arguments:      { x0, t0, tend, deltat, D, p, q, finallevel, nDIM, iterations }
:ArgumentTypes:  { Real64, Real64, Real64, Real64, Real64, Real64, Real64, Real64, Integer32, Integer32 }
:ReturnType:     Manual
:End:

The relevant part of my c++ code is given here:

#include "mathlink.h"
using namespace std;
extern void output(MLINK mlp, double x0, double t0, double tend, double deltat, double D, double p, double q, double finallevel, int nDIM, int iterations);

class Solver()
{
etc. etc.
}
void output(MLINK mlp, double x0, double t0, double tend, double deltat, double D, double p, double q, double finallevel, int nDIM, int iterations)
{
    Solver s(x0, D, t0, tend, deltat, finallevel, p, q, nDIM);

    s.PropagationDelayDistributionSolver(iterations);

    MLPutReal64List(mlp, s.returntau(), iterations);
}

Where s.returntau returns an array of doubles from the class (again, the details aren't important). When I compile this code, I only get one error:

Error 2 $\quad \quad$ error LNK2019: unresolved external symbol _output referenced in function __tr0 C:\Users\SOM874\Documents\Visual Studio 2010\Projects\PDS5\PDS5\output.obj $\quad \quad$ PDS5

I don't see anything wrong when I look at the output.c file but I am a novice, I wouldn't know what to look for. Is there anything wrong which jumps out at you? Thanks in advance.

$\endgroup$
  • 1
    $\begingroup$ There are several problems here: 1. the :Pattern: part of the template must be a Mathematica pattern that will match any call of the function from within Mathematica. There's no such thing as Real64 in Mathematica. What you specify in :ArgumentTypes: a completely different thing, those are not patterns. The possible values for that are documented here and appear to be correct. $\endgroup$ – Szabolcs Feb 10 '15 at 20:31
  • $\begingroup$ The second problem is what sakra has just posted so I won't repeat that. $\endgroup$ – Szabolcs Feb 10 '15 at 20:31
  • $\begingroup$ And one more thing: in Mathematica, avoid names starting with capitals to make sure there's no collision with builtins. Specifically: do not use D. It has a builtin meaning. Use something else with lowercase, like dd. $\endgroup$ – Szabolcs Feb 10 '15 at 20:36
1
$\begingroup$

I guess that this is a linkage issue. The generated output.tm.c file is compiled a C code whereas "your code" is compiled as C++ code. Thus the function output will have C++ linkage while the function __tr0 expects the function to have C linkage. In your C++ code, declare the function with C linkage using extern "C", i.e.:

#include "mathlink.h"
using namespace std;
extern "C" void output(MLINK mlp, double x0, double t0, double tend, double deltat, double D, double p, double q, double finallevel, int nDIM, int iterations);
$\endgroup$
  • $\begingroup$ So in this case will I lose the C++ class functionality within the function? Will I have to rewrite the code so that it does not call a class? $\endgroup$ – Onias Feb 11 '15 at 13:37
  • $\begingroup$ No. The extern "C" makes the function output callable from both C and C++ code. In its implementation you are free to use C++ language features. $\endgroup$ – sakra Feb 11 '15 at 13:39

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.