MathLink Development in C (Unix and Linux)
This document describes how to compile and run
MathLink programs written in the C language on Linux/Unix systems. ("
MathLink and External Program Communication" describes how to write
MathLink programs in both the
Mathematica language and the C language.)
This document does not teach you, in general, how to use your compiler and other development tools, nor does it teach you how to program in C. If you have any trouble building or running your
MathLink programs, see the
"Troubleshooting" section at the end of this document.
Most of what is described in this document is Linux/Unix specific, and is applicable to all supported Linux/Unix platforms. To learn how to compile and run
MathLink programs for another platform, see the Developer Guide for that platform.
Supported Development Platforms
As a shared library,
MathLink can be used with any development environment that adheres to the standard calling conventions and binary interfaces as specified by the following compilers listed.
While some of the following compilers listed integrate with integrated development environments produced by the compiler creators, they also function equally well with a
make utility.
| $SystemID | C compiler | C++ compiler |
| AIX-Power64 | IBM XL C Enterprise Edition V8 .0 for AIX | IBM XL C++ Enterprise Edition V8.0 for AIX |
| HPUX-PA64 | HP92453-01 B.11.11.14 HP C Compiler | HP ANSI C++ B3910B A.03.67 |
| Linux | gcc - 3.2.3 20030502 (Red Hat Linux 3.2.3-52) | g++ - 3.2.3 20030502 (Red Hat Linux 3.2.3-52) |
| Linux-IA64 | Intel C 9.0 | Intel C++ 9.0 |
| Linux-x86-64 | gcc - 3.2.3 20030502 (Red Hat Linux 3.2.3-34) | g++ - 3.2.3 20030502 (Red Hat Linux 3.2.3-34) |
| Solaris-SPARC | Sun C 5.8 2005/10/13 | Sun C++ 5.8 2005/10/13 |
| Solaris-x86-64 | Sun C 5.8 Patch 121016-03 2006/06/07 | Sun C++ 5.8 Patch 121018-04 2006/08/02 |
Installing the MathLink Components
The
MathLink Developer Kit (MLDK) is located in the directory
$InstallationDirectory/SystemFiles/Links/MathLink/DeveloperKit/
$SystemID within your
Mathematica directory.
Recommended Installation
CompilerAdditions Installation
The
MathLink components that you will need to build
MathLink programs have already been installed by the
Mathematica installer. One way to use these components is to leave them in the
Mathematica directory and specify their full path name when you call your compiler. This approach is taken in the example "makefiles" in the section "
Building MathLink Programs".
An alternative is to copy these components ("
mathlink.h," "libML32i3.a," and "libML32i3.so") into directories in which your compiler will automatically search for such files. These directories are commonly /usr/include and /usr/lib, but may be different on your system. On many systems not all users have write access to these directories.
MathLinkExamples Installation
Copy the MathLinkExamples directory to your home directory.
Components of the MathLink Developer's Kit
The following is a description of each file or directory in the MLDK.
CompilerAdditions Directory
mathlink.h
mathlink.h is the header file that must be included in your C and C++ source files. It should be placed where your compiler can find it. You could copy this header file into the same directory as your source files that include it, or in the same location as the standard header files, or leave it where it is if you added the
MathLink directory to the search path for header files.
libML32i3.a/libML64i4.a
This is the static library that contains all the
MathLink functions. It should be included in your project. You could copy this library into the same directory as your source files, or leave it where it is if you added the
MathLink directory to the search path for libraries. The 32/64 indicates whether the library is a 32-bit or a 64-bit version of the
MathLink library.
libML32i3.so/libML64i3.a/(.sl on HPUX)
This is the dynamic shared library that contains all of the
MathLink functions. It should be included in your project. You could copy this library into the same directory as your source files, into a systemwide location such as /lib or /usr/lib, or leave it where it is if you added the
MathLink directory to the search path for libraries. The 32/64 indicates whether the library is a 32-bit or a 64-bit version of the
MathLink library.
mprep
mprep is an application that writes
MathLink programs automatically by processing "
template" files. It may be convenient to copy this application into the same directory as your project or to create an alias to it.
mcc
mcc is a script that preprocesses and compiles your
MathLink source files.
MathLinkExamples Directory
This directory contains the source code for some very simple
MathLink programs. By using this source code, you can learn how to build and run
MathLink programs without having to write any code yourself.
PrebuiltExamples Folder
This folder contains prebuilt versions of the example programs. "
Running MathLink Programs" describes how to run two of these programs. "
Building MathLink Programs" describes how to build them yourself using the source code in the MathLinkExamples folder.
Building MathLink Programs
The general procedure for building
MathLink programs is to include
mathlink.h in any C or C++ source files that make
MathLink function calls, to compile your source files, and then to link the resulting object code with the "libML32i3.a", "libML64i3", "libML32i3.so", or "libML64i3.so" library and any other standard libraries required by your application. If your application uses the
MathLink template mechanism, then your template files must first be processed into a C source file using
mprep.
Using MathLink Template Files
If your program uses the
MathLink template mechanism as described in "
MathLink and External Program Communication", you must simultaneously preprocess your source files that contain template entries using the
mprep application. (A template entry is a sequence of lines that contain template keywords. Each entry defines a
Mathematica function that when evaluated calls an associated C function.) When
mprep processes such source files, it converts template entries into C functions, passes other text through unmodified, and writes out additional C functions that implement a remote procedure call mechanism using
MathLink. The result is a C source file that is ready for compilation.
mprep addtwo.tm -o addtwotm.c
will produce a C source file "
addtwotm.c" from the template entries and other text in "
addtwo.tm". You would then compile the output file using the C compiler. If you use the "
make" utility to build your program, you could add a rule similar to the following one to your makefile.
addtwotm.c : addtwo.tm
mprep addtwo.tm -o addtwotm.c
Building MathLink programs
What follows is a sample makefile needed to build the sample programs in the MLDK, including "
addtwo" and "
factor". To build a sample program, in this case "
addtwo", evaluate the following command in the MathLinkExamples directory.
Using a Makefile
# This makefile can be used to build all or some of the sample
# programs. To build all of them, use the command
# 'make all'. To build one, say addtwo, use the command
# 'make addtwo'.
MLINKDIR = /usr/local/Wolfram/Mathematica/6.0/SystemFiles/Links/MathLink/DeveloperKit
SYS = Linux # Set this value with the result of evaluating $SystemID
CADDSDIR = ${MLINKDIR}/${SYS}/CompilerAdditions
INCDIR = ${CADDSDIR}
LIBDIR = ${CADDSDIR}
EXTRALIBS = -lm -lpthread -lrt # Set these with appropriate libs for your system.
MLLIB = ML32i3 # Set this to ML64i3 if using a 64-bit system
MPREP = ${CADDSDIR}/mprep
all : addtwo bitops counter factor factor2 factor3 quotient reverse sumalist
addtwo : addtwotm.o addtwo.o
${CC} -I${INCDIR} addtwotm.o addtwo.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
bitops : bitopstm.o bitops.o
${CC} -I${INCDIR} bitopstm.o bitops.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
counter : countertm.o
${CC} -I${INCDIR} countertm.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
factor : factor.o
${CC} -I${INCDIR} factor.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
factor2 : factor2.o
${CC} -I${INCDIR} factor2.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
factor3 : factor3.o
${CC} -I${INCDIR} factor3.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
quotient : quotient.o
${CC} -I${INCDIR} quotient.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
reverse : reversetm.o
${CC} -I${INCDIR} reversetm.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
sumalist : sumalisttm.o sumalist.o
${CC} -I${INCDIR} sumalisttm.o sumalist.o -L${LIBDIR} -l${MLLIB} ${EXTRALIBS} -o $@
.c.o :
${CC} -c -I${INCDIR} $<
addtwotm.c : addtwo.tm
${MPREP} $? -o $@
bitopstm.c : bitops.tm
${MPREP} $? -o $@
countertm.c : counter.tm
${MPREP} $? -o $@
reversetm.c : reverse.tm
${MPREP} $? -o $@
sumalisttm.c : sumalist.tm
${MPREP} $? -o $@
Use the following table to determine the extra libraries needed for linking MathLink programs on your system.
| $SystemID | EXTRALIBS |
| AIX-Power64 | -lm -lpthread -lc128 |
| HPUX-PA64 | -lm /usr/lib/libdld.sl /usr/lib/libm.0 -lpthread -lrt |
| Linux | -lm -lpthread -lrt |
| Linux-IA64 | -lm -lpthread -lrt |
| Linux-x86-64 | -lm -lpthread -lrt |
| Solaris-SPARC | -lm -lsocket -lnsl -lrt |
| Solaris-x86-64 | -lm -lsocket -lnsl -lrt |
Using mcc
mcc is a script that preprocesses and compiles your
MathLink source files. It will preprocess
MathLink templates in any file whose name ends with
.tm, and then call "
cc" on the resulting C source code.
mcc will pass command-line options and other files directly to
cc. Following is a command that would build the "
addtwo" application using
mcc.
mcc addtwo.tm addtwo.c -o addtwo
Running MathLink Programs
The instructions in "
Building MathLink Programs" describe how to build two
MathLink programs using source code in the "MathLinkExamples" directory. These two programs, "
addtwo" and "
factor", are already built for you in the "PrebuiltExamples" folder. Before building them on your own, you should try to run the prebuilt examples to verify that the
MathLink system additions are installed and working and to learn what to expect from these examples when they are properly built.
There are two basic types of
MathLink program, epitomized by the "
addtwo" and "
factor" programs. The first is an installable program. An Installable program provides new functionality to the kernel by linking a C program to the kernel through a calling mechanism. In order to get this new functionality, the user of
Mathematica must run the
Install[] function. With the "
addtwo" example you will be adding a new function called
AddTwo[] that adds two numbers (provided as arguments) together. The kernel and installable programs have a special relationship that allows them only to communicate with one another. When an installable program is run it requires that you provide some information in order for it to connect. The other type of program is a front end. Front ends do all of the work of creating and managing their own links. In addition to the "
factor" example, the
Mathematica front end and the
Mathematica kernel are also example of the front end type. A front end does not require any extra information in order to run, but it will usually make a connection at some point during its execution.
Running a Prebuilt Example from the Mathematica Kernel
The first example program, "
addtwo", is a
MathLink template program that is installed into
Mathematica. That is, this program runs in the background, providing, as a service to
Mathematica, one or more externally compiled functions. To the
Mathematica user, these functions appear to be built-in. The "
addtwo" program uses a template file that defines the
Mathematica function
AddTwo[] as a call to the C function
addtwo(). (The template mechanism is described in "
MathLink and External Program Communication".) The source code for this program looks likes this.
:Begin:
:Function: addtwo
:Pattern: AddTwo[i_Integer, j_Integer]
:Arguments: { i, j }
:ArgumentTypes: { Integer, Integer }
:ReturnType: Integer
:End:
:Evaluate: AddTwo::usage = "AddTwo[x, y] gives the sum of two machine integers x and y."
int addtwo( int i, int j)
{
return i+j;
}
int main(int argc; char* argv[])
{
return MLMain(argc, argv);
}
Edit the path string and evaluate the following two cells. |
To see a list of the newly available functions, evaluate this cell. |
This displays the usage message for the AddTwo[] function as defined in the file "addtwo.tm". |
See what happens if the sum of the two machine integers will not fit in a machine integer or if either argument is not a machine integer. ( 2^31-1 is the largest machine integer. If your compiler uses 2-byte integers, the 2^15-1 is the largest C int.) |
The " addtwo" program is not prepared for big integers: |
This does not match AddTwo[_Integer, _Integer]: |
Install[] called LinkOpen[] and then exchanged information with the external program to set up the definition for AddTwo[]. You really do not have to worry about these details, but if you are curious, evaluate the following. |
When you are finished using the external program, evaluate the following. |
Invoking the Mathematica Kernel from Within a Prebuilt Example
The second example program, "
factor", is a
Mathematica front end in the sense that the
Mathematica kernel runs in the background providing, as a service to "
factor", the computational services of the kernel—in this case the ability to factor an integer typed by the user.
Launch the "
factor" application by executing the following command:
factor -linkmode launch -linkname 'math -mathlink'
After a moment, a prompt will appear requesting that you type an integer. Type an integer with fewer than 10 digits and press the
Enter key. (The other factor examples relax the restriction on the size of integer you may type in.)
The prime factors returned by
Mathematica are printed and "
factor" closes its link with
Mathematica.
Integer to factor: 123456789
3 ^ 2
3607 ^ 1
3803 ^ 1
Supported Link Protocols
The C function
MLOpenArgcArgv() and the
Mathematica function
LinkOpen[] are documented in "
MathLink and External Program Communication". On Linux/Unix machines, the legal values for the
LinkProtocol option are
"TCPIP",
"TCP",
"SharedMemory", and
"Pipes". A
LinkProtocol is the mechanism used to transport data from one end of a connection to the other.
"Pipes" is the default protocol for all
LinkMode->Launch links.
"SharedMemory" is the default protocol for all
LinkMode->Listen and
LinkMode->Connect links.
Note that link names are unsigned 16-bit integers for the
"TCPIP" and
"TCP" protocols. Even though
"TCPIP" link names are integers, they are still given as strings (of digits) to
MLOpenArgcArgv() and
LinkOpen[].
Troubleshooting
- Turn off compiler optimization until your program is working. This makes compiling faster, debugging easier, and, besides, the optimizer may be broken and the cause of some problems. (Optimized code uses the stack and registers differently than unoptimized code in such a way that may expose or mask a bug in your code. For example, the common mistake of returning a pointer to a local variable may or may not cause a problem depending on stack and register use.)
- Check the return values from the MathLink library functions or call MLError() at key points in your program. MathLink will often be able to tell you what has gone wrong.
- The files "mathlink.h", "libML32i3.a", and "libML32i3.so" (libML64i3.* on 64-bit platforms) are a matched set. If you have used an earlier release of MathLink, you should take care that you do not mix components when building your application.
- Check whether the C compiler you are using supports prototypes. If it does not, you will need to change your code and the way you build your project. This is explained in the section "Building MathLink Programs".