I am using MathLink with C/C++ on a Unix system in order to call a Mathematica (version 9) function and get the result.
The function I need to call is a personal function of mine MyFunct[x,y,z]
. The function takes three arguments and will return a Real
. This function is defined in myscript.m
file at this path: /home/myuser/Documents/mym/myscript.m
.
I have the following C code:
#include <mathlink.h>
#include <stdio.h>
int main(int argc, char** argv) {
MLENV env = (MLENV)0;
MLINK ml = (MLINK)0;
// Init and open
env = MLInitialize((char*)0);
int err = 0;
char* argv[5];
argv[0] = "ml";
argv[1] = "-linkmode";
argv[2] = "launch";
argv[3] = "-linkname";
argv[4] = "/usr/local/Mathematica/9.0/Executables/MathLink";
*link = MLOpenArgcArgv(*env, 5, argv, &err);
fprintf(stdout, "All ok!\n");
// Putting function
MLPutFunction(ml, "N", 1);
MLPutFunction(ml, "Cos", 1);
MLPutInteger(ml, 2);
MLEndPacket(ml);
MLFlush(ml);
// Getting
int pkt;
while ((pkt = MLNextPacket(ml),pkt) && pkt != RETURNPKT) {
MLNewPacket(ml);
if (MLError(ml)) fprintf(stdout, "Error!\n");
}
double r = 0;
MLGetReal(ml, &r);
fprintf(stdout, "Got %f!\n", r);
// Close and deinit
envCloseLink(&ml);
fprintf(stdout, "Closed!\n");
envDeInitEnv(&env);
fprintf(stdout, "Deinitialized!\n");
fprintf(stdout, "Over!\n");
}
The above code works! Now consider the following:
int main(int argc, char** argv) {
MLENV env = (MLENV)0;
MLINK ml = (MLINK)0;
// Init and open
env = MLInitialize((char*)0);
int err = 0;
char* argv[5];
argv[0] = "ml";
argv[1] = "-linkmode";
argv[2] = "launch";
argv[3] = "-linkname";
argv[4] = "/usr/local/Mathematica/9.0/Executables/MathLink";
*link = MLOpenArgcArgv(*env, 5, argv, &err);
fprintf(stdout, "All ok!\n");
// CALLING 'GET' ////////////////////////////////////////////////////////
fprintf(stdout, "Putting [GET]...\n");
if (!MLPutFunction(ml, "Get", 1)) fprintf(stdout, "Err!\n");;
if (!MLPutString(ml, "/home/myuser/Documents/mym/myscript.m")) fprintf(stdout, "Err!\n");
MLEndPacket(ml);
if (!MLFlush(ml)) fprintf(stdout, "Err!\n");
int pkt = 0;
while ((pkt = MLNextPacket(ml),pkt) && pkt != RETURNPKT) {
MLNewPacket(ml);
if (MLError(ml)) fprintf(stdout, "Error!\n");
}
// END //////////////////////////////////////////////////////////////////
// CALLING FUNCT ////////////////////////////////////////////////////////
fprintf(stdout, "Calling impulse...\n");
MLPutFunction(ml, "MyFunct", 3);
MLPutInteger(ml, 1);
MLPutInteger(ml, 4);
MLPutInteger(ml, 2);
MLEndPacket(ml);
MLFlush(ml);
int pkt2 = 0;
while ((pkt2 = MLNextPacket(ml),pkt2) && pkt2 != RETURNPKT) {
MLNewPacket(ml);
if (MLError(ml)) fprintf(stdout, "Error!\n");
}
double r = 0;
if (!MLGetReal(ml, &r)) fprintf(stdout, "Error in getting!\n"); // LINE REF1
fprintf(stdout, "Got %f\n", r);
// END //////////////////////////////////////////////////////////////////
// Close and deinit
envCloseLink(&ml);
fprintf(stdout, "Closed!\n");
envDeInitEnv(&env);
fprintf(stdout, "Deinitialized!\n");
fprintf(stdout, "Over!\n");
}
I got an error in LINE REF1
. I understood that the problem is the CALLING 'GET'
block. If I delete this block and call a Mathematica built in function (like in the previous code), I get no errors. But if I insert the block CALLING 'GET'
and then try to call one of the functions defined in my external file or a built in Mathematica function, errors are raised at the specified line (LINE REF1
).
Maybe I've made a mistake when trying to perform two sequential operations on the link... How do I solve this?