2.6 The MathLink Interface
MathLink is the low-level interface that is the root of all link objects in J/Link. The methods in MathLink correspond roughly to a subset of those in the C-language MathLink API. Most programmers will deal instead with objects of type KernelLink, a higher-level interface that extends MathLink and incorporates the assumption that the program on the other side of the link is a Mathematica kernel.
We will not have much to say here about most of these methods, as they behave like their C API counterparts in most respects. The JavaDoc help files are the main method-by-method documentation for all the J/Link classes and interfaces. They can be found in the JLink/Documentation/JavaDoc directory. This section is provided mainly for those who want to skim a traditional printed listing.
These are all public methods (the public has been left off to keep lines short).
2.6.1 Managing Links
void connect() throws MathLinkException;
// Wait at most timeoutMillis for the connect to occur, then throw a MathLinkException
void connect(long timeoutMillis) throws MathLinkException;
//A synonym for connect. This is the newer name.
void activate() throws MathLinkException;
2.6.2 Packet Functions
//Does not throw exception because it will often be needed in a catch block.
int nextPacket() throws MathLinkException;
void endPacket() throws MathLinkException;
2.6.3 Error Handling
void setError(int err);
2.6.4 Link State
boolean ready() throws MathLinkException;
Putting expressions on the link is a bit different in Java than C because Java lets you overload functions. Thus, there is no need to have methods with names like the C functions MLPutInteger and MLPutDouble; it suffices to have a single function named put() that has different definitions for each argument type. The only exceptions to this are the few cases where the argument needs to be interpreted in a special way. For example, there are three "put" methods that take a single string argument: put() (equivalent to the C-language function MLPutUnicodeString), putSymbol() (equivalent to MLPutUnicodeSymbol), and putByteString() (equivalent to MLPutByteString).
For numeric types, there are the following methods (there is no need to provide a put() method for byte, char, and short types, as these can be automatically promoted to int):
void put(int i) throws MathLinkException;
void put(long i) throws MathLinkException;
void put(double d) throws MathLinkException;
For strings and symbols:
void put(String s) throws MathLinkException;
void putByteString(byte b) throws MathLinkException;
void putSymbol(String s) throws MathLinkException;
All the J/Link methods that put or get strings use Unicode, which is the native format for Java strings..
For booleans, a Java true is sent as the Mathematica symbol True, and False for Java false:
void put(boolean b) throws MathLinkException;
There is also a put() method for arbitrary Java objects. In the default implementation, this does not do anything very useful for most objects (what it does is send obj.toString()). A handful of objects, however, have a meaningful representation to Mathematica. These are arrays, strings, Expr objects (discussed elsewhere), and instances of the so-called "wrapper" classes (Integer, Double, Character, and so on), which hold single numeric values. Arrays are sent as lists, strings are sent as Mathematica strings, and the wrapper classes are sent as their numeric value. (The last case is for complex numbers, which will be discussed later.)
void put(Object obj) throws MathLinkException;
There is a special method for arrays that lets you specify the heads of the array in each dimension. The heads are passed as an array of strings. Note that unlike the C counterparts (MLPutIntegerArray, MLPutDoubleArray, and so on), you do not have to specify the depth or dimensions because they can be inferred from the array itself:
void put(Object array, String heads) throws MathLinkException;
For putting Mathematica functions:
void putFunction(String f, int argCount) throws MathLinkException;
For transferring expressions from one link to another (the 'this' link is the destination):
void transferExpression(MathLink source) throws MathLinkException;
void transferToEndOfLoopbackLink(LoopbackLink source) throws MathLinkException;
Low-level "textual interface":
void putNext(int type) throws MathLinkException;
void putArgCount(int argCount) throws MathLinkException;
void putSize(int size) throws MathLinkException;
int bytesToPut() throws MathLinkException;
void putData(byte data) throws MathLinkException;
void putData(byte data, int len) throws MathLinkException;
Because you cannot overload methods on the basis of return type, there is no catchall get() method for reading from the link, as is the case with the put() method. Instead, there are separate methods for each data type. Notice that unlike their counterparts in the C API, these methods return the actual data that was read, not an error code (exceptions are used for errors, as with all the methods).
int getInteger() throws MathLinkException;
long getLongInteger() throws MathLinkException;
double getDouble() throws MathLinkException;
String getString() throws MathLinkException;
byte getByteString(int missing) throws MathLinkException;
String getSymbol() throws MathLinkException;
boolean getBoolean() throws MathLinkException;
Arrays of the nine basic types (boolean, byte, char, short, int, long, float, double, String), as well as complex numbers, can be read with a set of methods of the form getXXXArrayN(), where XXX is the data type and N specifies the depth of the array. For each type there are two methods like the following examples for int. There is no way to get the heads of the array using these functions (it will typically be "List" at every level). If you need to get the heads as well, you should use getExpr() to read the expression as an Expr and then examine it using the Expr methods.
int getIntArray1() throws MathLinkException;
int getIntArray2() throws MathLinkException;
... and others for all the eight primitive types and String and the complex class
Note that you do not have to know exactly how deep the array is to use these functions. If you call, say, getFloatArray1(), and what is actually on the link is a matrix of reals, then the data will be flattened into the requested depth (a one-dimensional array in this case). Unfortunately, if you do this you cannot determine what the original depth of the data was. If you call a function that expects an array of depth greater than the actual depth of the array on the link, it will throw a MathLinkException.
If you need to read an array of depth greater than 2 (but a maximum of 5) , you can use the getArray() method. The getXXXArrayN() methods discussed above are just convenience methods that use getArray() internally. The type argument must be one of TYPE_BOOLEAN, TYPE_BYTE, TYPE_CHAR, TYPE_SHORT, TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, TYPE_EXPR, TYPE_BIGINTEGER, TYPE_BIGDECIMAL, or TYPE_COMPLEX.
Object getArray(int type, int depth) throws MathLinkException;
// New in J/Link 2.0:
Object getArray(int type, int depth, String heads) throws MathLinkException;
New in J/Link 2.0 is getArray(int type, int depth, String heads). It reads an array and also tells you the heads at each level. See the JavaDocs for more information.
Unlike the C MathLink API, there are no methods for "disowning" strings or arrays because this is not necessary. When you read a string or array off the link, your program gets its own copy of the data, so you can write into it if you desire (although Java strings are immutable).
The getFunction() method needs to return two things: the head and the argument count. Thus, there is a special class called MLFunction that encapsulates both these pieces of information, and this is what getFunction() returns. The MLFunction class is documented later.
MLFunction getFunction() throws MathLinkException;
// Returns the function's argument count. Throws MathLinkException if the function
// is not the specified one.
int checkFunction(String f) throws MathLinkException;
//Throws an exception if the incoming function does not have this head and arg count.
void checkFunctionWithArgCount(String f, int argCount) throws MathLinkException;
These methods support the low-level interface for reading from a link.
int getNext() throws MathLinkException;
int getType() throws MathLinkException;
int getArgCount() throws MathLinkException;
int bytesToGet() throws MathLinkException;
byte getData(int len) throws MathLinkException;
Reading Expr objects:
public Expr getExpr() throws MathLinkException;
// Gets an expression off the link, then resets the link to the state
// prior to reading the expr. You can "peek" ahead without consuming anything
// off the link.
public Expr peekExpr() throws MathLinkException;
The messages referred to by the following functions are not Mathematica warning messages, but a low-level type of MathLink communication used mainly to send interrupt and abort requests. The getMessage() and messageReady() methods no longer function in J/Link 2.0. You must use setMessageHandler() if you want to receive messages from Mathematica.
int getMessage() throws MathLinkException;
void putMessage(int msg) throws MathLinkException;
boolean messageReady() throws MathLinkException;
long createMark() throws MathLinkException;
//Next two don't throw, since they are often used in cleanup operations in catch handlers.
void seekMark(long mark);
void destroyMark(long mark);
2.6.9 Complex Class
The setComplexClass() method lets you assign the class that will be mapped to complex numbers in Mathematica. "Mapped" means that the put(Object) method will send a Mathematica complex number when you call it with an object of your complex class, and getComplex() will return an instance of this class. For further discussion about this subject and the restrictions on the classes that can be used as the complex class, see Section 1.2.14.
public boolean setComplexClass(Class cls);
public Class getComplexClass();
public Object getComplex() throws MathLinkException;
2.6.10 Yield and Message Handlers
The setYieldFunction() and addMessageHandler() methods take a class, an object, and a method name as a string. The class is the class that contains the named method, and the object is the object of that class on which to call the method. Pass null for the object if it is a static method. The signature of the method you use in setYieldFunction() must be V(Z); for addMessageHandler() it must be II(V). See Section 2.15 for more information and examples.
public boolean setYieldFunction(Class cls, Object obj, String methName);
public boolean addMessageHandler(Class cls, Object obj, String methName);
public boolean removeMessageHandler(String methName);
The MathLink class also includes the full set of user-level constants from MathLink.h. They have exactly the same names in Java as in C. In addition, there are some J/Link-specific constants.
static int ILLEGALPKT;
static int CALLPKT;
static int EVALUATEPKT;
static int RETURNPKT;
static int INPUTNAMEPKT;
static int ENTERTEXTPKT;
static int ENTEREXPRPKT;
static int OUTPUTNAMEPKT;
static int RETURNTEXTPKT;
static int RETURNEXPRPKT;
static int DISPLAYPKT;
static int DISPLAYENDPKT;
static int MESSAGEPKT;
static int TEXTPKT;
static int INPUTPKT;
static int INPUTSTRPKT;
static int MENUPKT;
static int SYNTAXPKT;
static int SUSPENDPKT;
static int RESUMEPKT;
static int BEGINDLGPKT;
static int ENDDLGPKT;
static int FIRSTUSERPKT;
static int LASTUSERPKT;
//These next two are unique to J/Link.
static int FEPKT;
static int EXPRESSIONPKT;
static int MLTERMINATEMESSAGE;
static int MLINTERRUPTMESSAGE;
static int MLABORTMESSAGE;
static int MLTKFUNC;
static int MLTKSTR;
static int MLTKSYM;
static int MLTKREAL;
static int MLTKINT;
static int MLTKERR;
//Constants for use in getArray()
static int TYPE_BOOLEAN;
static int TYPE_BYTE;
static int TYPE_CHAR;
static int TYPE_SHORT;
static int TYPE_INT;
static int TYPE_LONG;
static int TYPE_FLOAT;
static int TYPE_DOUBLE;
static int TYPE_STRING;
static int TYPE_BIGINTEGER;
static int TYPE_BIGDECIMAL;
static int TYPE_EXPR;
static int TYPE_COMPLEX;