Write C/C++ programs calling Mathematica functions
Have a look at this;
http://reference.wolfram.com/mathematica/guide/MathLinkCLanguageFunctions.html
I haven't used it in C/C++ but it works fine in C# and Java. Basically you create a connection to a Mathematica kernel and then pass it native data types. Works nicely.
Here is some sample code in Java that I used when I first did this;
import com.wolfram.jlink.*;
public class SampleProgram {
public static void main(String[] argv) {
KernelLink ml = null;
try {
ml = MathLinkFactory.createKernelLink(argv);
} catch (MathLinkException e) {
System.out.println("Fatal error opening link: " + e.getMessage());
return;
}
try {
// Get rid of the initial InputNamePacket the kernel will send
// when it is launched.
ml.discardAnswer();
ml.evaluate("<<MyPackage.m");
ml.discardAnswer();
ml.evaluate("2+2");
ml.waitForAnswer();
int result = ml.getInteger();
System.out.println("2 + 2 = " + result);
// Here's how to send the same input, but not as a string:
ml.putFunction("EvaluatePacket", 1);
ml.putFunction("Plus", 2);
ml.put(3);
ml.put(3);
ml.endPacket();
ml.waitForAnswer();
result = ml.getInteger();
System.out.println("3 + 3 = " + result);
// If you want the result back as a string, use evaluateToInputForm
// or evaluateToOutputForm. The second arg for either is the
// requested page width for formatting the string. Pass 0 for
// PageWidth->Infinity. These methods get the result in one
// step--no need to call waitForAnswer.
String strResult = ml.evaluateToOutputForm("4+4", 0);
System.out.println("4 + 4 = " + strResult);
} catch (MathLinkException e) {
System.out.println("MathLinkException occurred: " + e.getMessage());
} finally {
ml.close();
}
}
}
The connection string argv should look something like this
String argv = "-linkmode launch -linkname 'C:\\Program Files\\Wolfram Research\\Mathematica\\8.0\\mathkernel.exe'";
http://reference.wolfram.com/mathematica/JLink/tutorial/WritingJavaProgramsThatUseMathematica.html
The other answers ignore that you are asking about C or C++ (not C# or Java!)
Mathematica can be called from C (or C++) through the MathLink interface (recently renamed to WSTP). To learn it, I recommend reading this old MathLink tutorial by Todd Gayley:
- Original version in PostScript: http://library.wolfram.com/infocenter/Demos/174/
- PDF conversion: http://edenwaith.com/development/tutorials/mathlink/ML_Tut.pdf
Section 2 discusses what you are asking for: calling Mathematica from a C program rather than the reverse case (which is better covered in the official documentation)
You will find several example programs (like factor.c
) in the directory opened by this command:
SystemOpen@
FileNameJoin[{$InstallationDirectory, "SystemFiles", "Links",
"MathLink", "DeveloperKit", $SystemID, "MathLinkExamples"}]
It is also useful to experiment with setting up MathLink connections in pure Mathematica code. This will help you understand the basic procedure before you try to implement the same in C:
- http://reference.wolfram.com/language/tutorial/CallingSubsidiaryWolframSystemProcesses.html
C Style
To Call Mathematica functions from C/C++
you need to use ML_
or WS_
functions. Mathematica is now "replacing" MathLink
with WSTP
. However function names are mostly similar. There are C style WSPutT
functions that are used to send an input of type T
to mathematica. and the output is fetched from mathematica using WSNextPacket
and WSGetT
functions. To use these accessing functions first a link needs to be established WSOpenArgcArgv
. The C language Reference lists the functions that you will need to communicate with mathematica using
C/C++
C++ (with mathematica++)
I was mostly interested to use mathematica from C++. So I developed one C++ library mathematica++
that uses template magic for easier interoperability between C++ and Mathematica. The usage example below is copied from the project page.
symbol x("x");
value res;
std::string method = "Newton";
shell << Values(FindRoot(ArcTan(1000 * Cos(x)), List(x, 1, 2), Rule("Method") = method));
shell >> res;
std::vector<double> results = cast<std::vector<double>>(res);
std::cout << results[0] << std::endl; // Prints 10.9956
With mathematica++
you declare a mathematica function using MATHEMATICA_DECLARE(FunctionName)
and then use the function FunctionName
in C++. Like in the example above FindRoot
is being used to solve the equation. It builds an equivalent chain of WS_
functions on runtime. The template function cast<T>
can be sued to cast mathematica returned results back to C++ STL
types.
symbol i("i"); // declare mathematica symbol i
value result_list; // declare the variable to hold the result
shell << Table(i, List(i, 1, 10)); // In Mathematica Table[i, {i, 1, 10}]
shell >> result_list;
std::cout << result_list << std::endl; // Prints List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
std::cout << result_list->stringify() << std::endl; // Prints List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
std::vector<int> list;
list = cast<std::vector<int>>(result_list);
shell.import("/path/to/package.m")
can be used to import a mathematica package.
shell << Import("/path/to/package.m")`
also yields the same as well. Because Import
is also a mathametica function that can be declared using MATHEMATICA_DECLARE
I have tested it only on Linux and Mac platforms, but it should work on windows also. The Project is in Free BSD License.
mathematica++ gitlab repository | website | wiki