# Two-Way Communication with External Programs

When you install a *MathLink*-compatible external program using Install, the program is set up to behave somewhat like a simplified *Mathematica* kernel. Every time you call a function in the external program, a CallPacket is sent to the program, and the program responds by sending back a result wrapped in a ReturnPacket.

In[1]:= |

Out[1]= |

In[3]:= |

In[4]:= |

Out[4]= |

If you use Install several times on a single external program, *Mathematica* will open several *MathLink* connections to the program. Each connection will however always correspond to a unique LinkObject.

$CurrentLink | the MathLink connection to the external program currently being run |

Identifying different instances of a single external program.

:Begin:

:Function: addto

:Pattern: addto[$CurrentLink, n_Integer]

:Arguments: n

:ArgumentTypes: Integer

:ReturnType: Integer

:End:

int counter = 0;

int addto(int n)

counter += n;

return counter;

In[5]:= |

Out[5]= |

In[6]:= |

Out[6]= |

In[7]:= |

Out[7]= |

In[8]:= |

Out[8]= |

In[9]:= |

Out[9]= |

If an external program maintains information about its state then you can use different instances of the program to represent different states. $CurrentLink then provides a way to refer to each instance of the program.

The value of $CurrentLink is temporarily set every time a particular instance of the program is called, as well as when each instance of the program is first installed.

MLEvaluateString(stdlink,"string") | send input to Mathematica but return no results |

Sending a string for evaluation by *Mathematica*.

The two-way nature of *MathLink* connections allows you not only to have *Mathematica* call an external program, but also to have that external program call back to *Mathematica*.

In the simplest case, you can use the *MathLink* function to send a string to *Mathematica*. *Mathematica* will evaluate this string, producing whatever effects the string specifies, but it will not return any results from the evaluation back to the external program.

To get results back you need explicitly to send an EvaluatePacket to *Mathematica*, and then read the contents of the ReturnPacket that comes back.

MLPutFunction(stdlink, "EvaluatePacket", 1);

MLPutFunction(stdlink, "Factorial", 1);

MLPutInteger32(stdlink, 7);

MLEndPacket(stdlink);

MLCheckFunction(stdlink, "ReturnPacket", &n);

MLGetInteger32(stdlink, &ans);

MLEndPacket(stdlink) | specify that a packet is finished and ready to be sent to Mathematica |

Sending a packet to *Mathematica*.

When you can send *Mathematica* an EvaluatePacket[input], it may in general produce many packets in response, but the final packet should be ReturnPacket[output]. "Manipulating Expressions in External Programs" discusses how to handle sequences of packets and expressions whose structure you do not know in advance.