|
2.8.2 The MathLink "Packet Loop"
In a C MathLink program, a typical code fragment for sending a computation to Mathematica and throwing away the result might look like this:
// C code
MLPutFunction(ml, "EvaluatePacket", 1);
MLPutFunction(ml, "ToExpression", 1);
MLPutString(ml, "Needs[\"MyPackage`\"]");
MLEndPacket(ml);
while (MLNextPacket(ml) != RETURNPKT)
MLNewPacket(ml);
MLNewPacket();
After sending the computation (wrapped in an EvaluatePacket), the code enters a while loop that reads and discards packets until it encounters the ReturnPacket, which will contain the result (which will be the symbol Null here). Then it calls MLNewPacket once again to discard the ReturnPacket.
A MathLink program will typically do this same basic operation many times, so J/Link hides it within some higher-level methods in the KernelLink interface. Here is the J/Link equivalent:
ml.evaluate("Needs[\"MyPackage`\"]");
ml.discardAnswer();
The discardAnswer() method discards all packets generated by the computation until it encounters the one containing the result, and then discards that one too. There is a related method, waitForAnswer(), that discards everything up until the result is encountered. When waitForAnswer() returns, the ReturnPacket has been opened and you are ready to read out its contents. You can probably guess that discardAnswer() is just waitForAnswer() followed by newPacket().
Not only is it a convenience to hide the packet loop within waitForAnswer() and discardAnswer(), it is necessary in some circumstances, since special packets may arrive that J/Link needs to handle internally. Although J/Link has nextPacket() and newPacket() methods, programmers should not write nextPacket()/newPacket() loops like the one in the C code fragment above. Stick to calling waitForAnswer(), discardAnswer(), or using the "evaluateTo" methods discussed in the next section. If you really need to know about all the packets that arrive in your program, use the PacketListener interface, discussed later.
|