5
$\begingroup$

In Mathematica I can make the assignment 'foo = bar' with Set[foo,bar]. However, if I try to evaluate 'Set[foo,bar]' through MathLink then it appears that MathLink gets stuck while trying to read additional information from the link. Here's a small sample program, "myassignment.tm" :

void myAssignment P(( ));

:Begin:         
:Function:  myAssignment
:Pattern:   myAssignment[ ]
:Arguments: { }
:ArgumentTypes: { }
:ReturnType:    Manual
:End:

#include "mathlink.h"
#include <stdio.h>

void myAssignment() 
{ 
  MLPutFunction( stdlink, "EvaluatePacket", 1 );
    MLPutFunction( stdlink, "Set", 2 );
      MLPutSymbol( stdlink, "foo" ); 
      MLPutSymbol( stdlink, "bar" ); 
  MLEndPacket( stdlink );
  MLNextPacket( stdlink ); /* Get return packet */
  MLNewPacket( stdlink ); /* Discard return value, which is simply 'bar' */ 
}

int main(int argc, char *argv[]) { return MLMain(argc, argv); }

I have kept the sample program here short and concise. Adding error checking for every MathLink statement and printing out all the packets received after the assignment and their content doesn't reveal any additional information. It appears to hang after the last MLNewPacket statement has been executed. I could possibly install a yield-function, but I'd much rather understand why Mathematica is blocking at this point. Does anyone have any insights into this ?

Edit : Ultimately my goal is to assign default values to optional arguments of a function. Hence I want something equivalent to this :

Options[ foo ] = { bar->42 };

The actual name of the optional argument is not bar and the default value is not 42. Instead both are obtained by a call into a C library, which is why all of this has to happen through MathLink. Assuming I solve the assignment problem described above I can set the default value(s) by creating the list of rule(s) and the assignment through MathLink.

I'd like these default values to be put in place when the program is installed, so I would also add this to my template :

:Evaluate: myAssignment[]; 

Alternatively I can avoid the assignment in MathLink by just creating the list of rule(s) in MathLink (in which case I'll call the function myRules) and then add this line to the template :

:Evaluate: Options[ foo ] = myRules[]

Unfortunately, none of the above solutions work for me, and it also fails with the simplification proposed by @halirutan.

$\endgroup$
  • $\begingroup$ I have also faced this issue when using mathlink. To solve this I read the return of the assignment. MLPutFunction("Set", 2) MLPutFunction("MessageName", 2) MLPutSymbol("LibraryFunction") MLPutString("argx") MLPutString("called with 1` argument(s) 2 argument(s) is expected.")` MLEndPacket() MLNextPacket() MLNewPacket() MLPutFunction("Set", 2) The last Put gave me MLEABORT "a put or get was aborted before affecting the link" $\endgroup$ – Neel Basu Oct 23 '18 at 19:48
2
$\begingroup$

Something simple like

void myAssignment P(( ));

:Begin:         
:Function:  myAssignment
:Pattern:   myAssignment[ ]
:Arguments: { }
:ArgumentTypes: { }
:ReturnType:    Manual
:End:

#include "mathlink.h"
#include <stdio.h>

void myAssignment() { 
    MLPutFunction( stdlink, "Set", 2 );
      MLPutSymbol( stdlink, "foo" ); 
      MLPutSymbol( stdlink, "bar" ); 
}

int main(int argc, char *argv[]) { return MLMain(argc, argv); }

and in Mathematica (adjust the path!)

exe = CreateExecutable[{"Documents/notebooks/SE/setML.tm"},
  "setML", "ShellOutputFunction" :> Print, 
  "ShellOutputFunction" :> Print];
lnk = Install[exe]
myAssignment[]

seems to work.

OwnValues[foo]
(* {HoldPattern[foo] :> bar} *)
$\endgroup$
  • $\begingroup$ This seems to work although I don't understand why an assignment doesn't have to be sent in an EvaluatePacket ? $\endgroup$ – Rasmus Apr 21 '14 at 23:57
  • $\begingroup$ While the proposed solution works as is, it seems to break again if you add :Evaluate: myAssignment[]; to the template. The goal of this would be to execute the assignment whenever the executable is installed. $\endgroup$ – Rasmus Apr 22 '14 at 0:02
  • $\begingroup$ @Rasmus If this was the goal of the exercise, why didn't you tell in your question? In this case, you can simply add :Evaluate: foo=bar to the template part! $\endgroup$ – halirutan Apr 22 '14 at 0:31
  • $\begingroup$ The real problem involves setting default values for a MathLink defined function with optional arguments where the defaults are obtained by calling into a C library. I wanted to keep the question as simple as possible, but I can add the extra details to the question. $\endgroup$ – Rasmus Apr 22 '14 at 2:48

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.