How Do I Incorporate C Code or External Programs in Mathematica?

On almost all computer systems, it is possible to run external programs directly from within Mathematica. You can use Mathematica to control external C programs, or exchange information and data with them.  Here we discuss some ways of running your external programs from Mathematica and setting up the MathLink communications API.

Exchanging Data via Interprocess Communication Mechanisms

On operating systems that support interprocess communication mechanisms such as pipes. Mathematica can communicate with external programs through these. In the simplest cases, the only communication you need is to send and receive plain text. In general, Mathematica allows you to treat streams of data exchanged with external programs just like files. In place of a file name, you give the external command to run, prefaced by an exclamation point.

<<"!command"

This tells Mathematica to run an external command and then read in the output it produces.

expr >> "!command"

This feeds the textual form of expr to an external command. In the example below, the expression x^2 + y^2 is fed as input to the external command lpr, which, on a typical Berkeley Unix system, sends output to a printer.

x^2 + y^2 >> "!lpr"

ReadList["!command", Number]

This runs an external command and then reads in a list of the numbers it produces. In the example below, the external command squares 4 is run and then Mathematica reads numbers from the output it produces.

ReadList["!squares 4", Number, RecordLists->True]

Special Note

With a text-based interface, putting ! at the beginning of a line causes the remainder of the line to be executed as an external command.

!squares 4

More Information on Using Interprocess Communication Mechanisms

See Section 1.11.10 of the Mathematica Book.

Linking C Code into Mathematica via MathLink

We just discussed how to exchange plain text with external programs. However, there are times when you will find it convenient to communicate with external programs at a higher level, and to exchange more structured data with them. To do this we use MathLink, a standardized protocol for two-way communication between external programs and Mathematica.

In order to use MathLink, an external program has to include some special source code, which is usually distributed with Mathematica. MathLink allows external programs both to call Mathematica, and to be called by Mathematica. This includes using Mathematica to call individual functions inside an external program. As described in Section 2.12 of the Mathematica Book, the process for communicating with external programs using MathLink is the following.

(1)  You set up a MathLink template file to specify how particular functions in Mathematica should call functions inside your external program.
(2)  From the MathLink template file, you generate source code to include in your program.
(3)  Then when you start your program, the appropriate Mathematica definitions are automatically made, and when you call a particular Mathematica function, code in your external program is executed.

Setting Up a MathLink Template File

If you have a function defined in an external program, then what you need to do in order to make it possible to call the function from within Mathematica is to add appropriate MathLink code that passes arguments to the function, and takes back the results it produces. In simple cases, you can generate the necessary code just by giving an appropriate MathLink template for each external function. MathLink templates are conventionally put in files with names of the form file.tm. Such files can also contain C source code, interspersed between templates for different functions.The elements of a MathLink template file include the following.

({{"\!\(\*StyleBox[\"\\\":Begin:\\\"\", \"MR\"]\) ", "begin the template for a particular function "}, {"\!\(\*StyleBox[\"\\\":Function:\\\"\", \"MR\"]\) ", "the name of the function in the external program "}, {"\!\(\*StyleBox[\"\\\":Pattern:\\\"\", \"MR\"]\) ", "the pattern to be defined to call the function "}, {"\!\(\*StyleBox[\"\\\":Arguments:\\\"\", \"MR\"]\) ", "the arguments to the function "}, {"\!\(\*StyleBox[\"\\\":ArgumentTypes:\\\"\", \"MR\"]\) ", "the types of the arguments to the function "}, {"\!\(\*StyleBox[\"\\\":ReturnType:\\\"\", \"MR\"]\) ", "the type of the value returned by the function "}, {"\!\(\*StyleBox[\"\\\":End:\\\"\", \"MR\"]\) ", "end the template for a particular function "}, {"\!\(\*StyleBox[\"\\\":Evaluate:\\\"\", \"MR\"]\) ", "\!\(\*StyleBox[\"\\\"Mathematica\\\"\", \"TI\"]\) input to evaluate when the function is installed "}})

Here is an example MathLink template file called f.tm.

:Begin:
:Function:      f
:Pattern:       f[x_Integer, y_Integer]
:Arguments:     {x, y}
:ArgumentTypes: {Integer, Integer}
:ReturnType:    Integer
:End:

Generating Source Code to Include in Your Program

Once you have constructed a MathLink template for a particular external function, you have to combine this template with the actual source code for the function. Assuming that the source code is written in the C programming language, you can do this just by adding a line to include the standard MathLink header file, and then inserting a small main program. Below is an example file, f.c, containing C source code.

Include the standard MathLink header file.

#include "mathlink.h"

Here is the actual source code for the function f.

int f(int x, int y) {
   return x+y;
}

This sets up the external program to be ready to take requests from Mathematica.

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

Note that the form of main required on different systems may be slightly different. The release notes included in the MathLink Developer's Kit on your particular computer system should give the appropriate form.

Once you have set up the appropriate files, you then need to process the MathLink template information, and compile all of your source code. Typically you do this by running various external programs, but the details will depend on your computer system. Under Unix, for example, the MathLink Developer's Kit includes a program named mcc which 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.

This preprocesses f.tm, then compiles the resulting C source file together with the file f.c.

mcc -o f.exe f.tm f.c

On systems other than Unix, the MathLink Developer's Kit typically includes a program named mprep, which you have to call directly, giving as input all of the .tm files that you want to preprocess. mprep will generate C source code as output, which you can then feed to a C compiler.

Calling the External Function from Mathematica

Now, we can call and use the external program from Mathematica. First, we use Install to let Mathematica know about the external program.

Install["f.exe"]

Now we call the external function f(int x, int y) and it adds two integers together.

f[6, 9]

More Information on Using MathLink

Much more information on using MathLink and setting up communications between Mathematica and external programs is available in the Mathematica Book and in the MathLink Developer Guide documentation. Take a look at these sections for more information.

The Mathematica Book

1.11.11
2.12

For the complete documentation, go to the Add-ons ⊳ MathLink Library documentation in the Help Browser. Among the information there, you'll find a general introduction to MathLink, how to use the various MathLink commands, and system-specific information.

Via Mathcode C++

The MathCode C++ code-generation system provides high performance, connectivity, and easy-to-use matrix arithmetic for the Mathematica developer. The core of the product is the translation of a subset of Mathematica code to C++, which can be compiled into standalone applications or easily called from Mathematica using the MathLink communications protocol. MathCode C++ works with Microsoft Visual C++ and CC/gcc on Unix platforms. More information about MathCode C++ is available on our website..