Calling the Wolfram Language from .NET
|What Is WSTP?
|Building and Deploying Programs
|Overview of the Main .NET/Link Interfaces and Classes
"Calling .NET from the Wolfram Language" describes using .NET/Link to allow you to call from the Wolfram Language into .NET, thereby extending the Wolfram Language environment to include the functionality in all existing and future .NET classes. This tutorial shows you how to use .NET/Link in the opposite direction, as a means to write .NET programs that use the Wolfram Language kernel as a computational engine.
.NET/Link uses the Wolfram Symbolic Transfer Protocol (WSTP), Wolfram Research's protocol for sending data and commands between programs. Many of the concepts and techniques in .NET/Link programming are the same as those for programming with the WSTP C-language API. The .NET/Link documentation is not intended to be an encyclopedic compendium of everything you need to know to write .NET programs that use WSTP. Programmers may have to rely a little on the general documentation of WSTP programming. The tutorial is divided into two major sections along the same lines as this documentation; you will want to read the second part. Many of the functions .NET/Link provides have C-language counterparts that are identical or nearly so. An old name for WSTP was MathLink, and this explains the appearance of that legacy name in several .NET/Link classes and interfaces.
You should at least skim the tutorial "Calling .NET from the Wolfram Language" at some point. Your .NET "front end" can use the same techniques for calling .NET methods from Wolfram Language code and passing .NET objects as arguments that programmers use when running the kernel from the notebook front end. This allows you to have a very high-level interface between .NET and the Wolfram Language. When you are writing WSTP programs in C, you have to think about passing and returning simple things like strings and integers. With .NET/Link you can pass .NET objects back and forth between .NET and the Wolfram Language.
The following sections merely provide an overview of topics in .NET/Link programming. The main class-by-class reference for .NET/Link is the API documentation. You should also look at the example programs.
When you are reading this text, or programming in .NET or the Wolfram Language, remember that the entire source code for .NET/Link is provided. If you want to see how anything works (or why it does not), you can always consult the source code directly.
The Wolfram Symbolic Transfer Protocol (WSTP) is a platform-independent protocol for communicating between programs. In more concrete terms, it is a means to send and receive Wolfram Language expressions. WSTP is the means by which the notebook front end and kernel communicate with each other. It is also used by a large number of commercial and freeware applications and utilities that link the Wolfram Language and other programs or languages. It is implemented as a library of C-language functions. .NET/Link brings the capabilities of WSTP into .NET in a way that is simpler to use and much more powerful than the raw C-level API.
The .NET/Link class library is written in an object-oriented style intended to maximize its extensibility in the future without requiring users' code to change. This requires a clean separation between interface and implementation. This is accomplished by exposing the main link functionality through interfaces, not classes. The names of the concrete classes that implement these interfaces will hardly be mentioned because programmers do not need to know or care what they are. Rather, you will use objects that belong to one of the interface types. You do not need to know what the actual classes are because you will never create an instance directly; instead, you will use a "factory method" to create an instance of a link class. This will become clear further on.
This section gives a brief overview of the main interfaces and classes. They will be discussed in more detail later. In addition, there is full documentation for the class library in the .NET/Link API documentation. Most of these classes and interfaces are in the Wolfram.NETLink namespace; others are in Wolfram.NETLink.UI.
The two most important link interfaces you need to know about are IMathLink and IKernelLink. The IMathLink interface is essentially a port of the WSTP C API into .NET. Most of the method names will be familiar to experienced WSTP programmers. IKernelLink extends IMathLink and adds some important high-level convenience methods that are only meaningful if the other side of the link is a Wolfram Language kernel (for example, the method WaitForAnswer(), which assumes the other side of the link will respond with a defined series of packets).
The basic idea is that the IMathLink interface encompasses all the operations that can be performed on a link without making any assumptions about what program is on the other side of the link. IKernelLink adds the assumption that the other side is a Wolfram Language kernel.
IKernelLink is the most important interface, as most programmers will work exclusively with it. Of course, since IKernelLink extends IMathLink, many of the methods you will use on your IKernelLink objects are declared and documented in the IMathLink interface.
The most important class that implements IMathLink is NativeLink, so named because it calls directly into Wolfram Research's WSTP library. In the future, other classes could be added that do not rely on native methods—for example, one that uses .NET remoting to communicate across a network. As discussed earlier, programmers do not need to be concerned about what these classes are, because they will never type a link class name in their code.
MathLinkFactory is the class that you use to create link objects. It contains the static methods CreateMathLink(), CreateKernelLink(), and CreateLoopbackLink(), which take various argument sequences. These are the equivalents of calling WSOpen in a C program.
MathLinkException is the exception class that is thrown by many of the methods in IMathLink and IKernelLink. The .NET/Link API uses exceptions to indicate errors, rather than function return values like the WSTP C API. In C, you write code that checks the return values like this.
In .NET/Link, you can wrap calls in a try block and catch MathLinkException.
The Expr class provides a direct representation of Wolfram Language expressions in .NET. Expr has a number of methods that provide information about the structure of the expression and that let you extract components. These methods have names and behaviors that will be familiar to Wolfram Language programmers—for example, Length(), Part(), NumberQ(), VectorQ(), Take(), Delete(), and so on. When reading from a link, instead of using the low-level IMathLink interface methods for discovering the structure and properties of the incoming expression, you can just read an entire expression from the link using GetExpr(), and then use Expr methods to inspect it or decompose it. For writing to a link, Expr objects can be used as arguments to some of the most important IKernelLink methods.
MathKernel is a non-visual component that provides a very high-level interface for interacting with the Wolfram Language. It is especially intended for use in visual programming environments, as it is highly configurable via properties. For many types of .NET programs that use the Wolfram Language for computations, the IKernelLink interface provides ideal functionality. For some types of programs, however, programmers might find the MathKernel object even easier to use. This is especially true for programs that want to capture not just the result of a computation, but also messages, Print output, or graphics generated as side effects of the computation.
The MathPictureBox class provides an easy way to display Wolfram Language graphics and typeset expressions. This class is often used from Wolfram Language code, but it is just as useful in .NET programs.
The .NET/Link distribution includes a SimpleLink sample program that demonstrates simple techniques for launching the Wolfram Language and performing computations. The code is available in both C# and Visual Basic .NET.
The .NET/Link assembly file is Wolfram.NETLink.dll, and it is found in the <Wolfram dir>\SystemFiles\Links\NETLink directory. When you compile .NET programs that use .NET/Link, you will need to add a reference to this file. In previous versions of .NET/Link, this assembly was placed into the .NET global assembly cache (GAC) by the Wolfram System installer. Starting with .NET/Link 1.2; however, the Wolfram.NETLink.dll assembly is no longer strong-named and therefore cannot be placed into the GAC. .NET programs that use .NET/Link will therefore need to have a copy of this assembly in their application directory, that is, right next to their .exe file. Alternatively, the Wolfram.NETLink.dll assembly can be located in a subdirectory of the application's directory, according to the standard rules for how .NET probes for assemblies that are not strong-named.
A consequence of the fact that Wolfram.NETLink.dll is not strong-named is that you can replace your application's copy with an updated version, and the updated version will be used without requiring the application to be recompiled. In contrast, strong-named assemblies in .NET are strictly versioned, so that when a program is compiled against a specific version of the assembly, the program can only run with that precise version. Of course, this strict versioning is touted as a benefit of .NET, and it is advantageous in certain circumstances, but for various technical reasons it is not desirable for Wolfram.NETLink.dll to be strong-named.
The .NET Framework SDK includes command-line compilers for several .NET languages, including C# and Visual Basic .NET. You can use these free tools without purchasing Visual Studio .NET and might want to use them to build simple programs even if you do have Visual Studio .NET.
The command-line compilers rely on several DOS environment variables being set correctly, so the .NET Framework SDK comes with a batch file named sdkvars.bat that you can run in your DOS session to set these variables. If you own Visual Studio .NET and want to use any command-line tools, use the Microsoft Visual Studio .NET/Visual Studio .NET Tools/Visual Studio .NET Command Prompt item on the Windows Start menu to launch a DOS session with all the required settings.
It is convenient to place a copy of Wolfram.NETLink.dll into your build directory before you compile, as you would otherwise need to include the full path to this assembly on the compiler command line, and you will need a copy of it to be present in the program's directory anyway. The following examples assume that you have copied (not moved!) the Wolfram.NETLink.dll file from <Mathematica dir>\SystemFiles\Links\NETLink into the directory in which you are performing the build. Here is a sample command for a C# program.
Programs that use .NET/Link need to have a reference to the Wolfram.NETLink.dll assembly in their project settings. You add a reference to an assembly by selecting Add Reference from the Project menu. The Wolfram System installer makes the necessary settings so that the Wolfram.NETLink.dll assembly shows up in the Add Reference dialog box. It will be listed as .NET/Link 1.3 in the .NET tab. If for some reason it does not show up there, you can simply use the Browse button to locate the file manually (it will be in the <Mathematica dir>\SystemFiles\Links\NETLink directory, or perhaps in another more convenient location if you put a copy elsewhere).
When Visual Studio .NET builds your program it will automatically place a copy of Wolfram.NETLink.dll in the output directory, alongside your .exe file. Your program will require a copy of Wolfram.NETLink.dll alongside it to run, so if you deploy your program to another location or distribute it to other users, you must keep the Wolfram.NETLink.dll file with it.
If you build a .NET program that uses .NET/Link and want to distribute it to others, you will need to include a copy of the Wolfram.NETLink.dll assembly alongside your application's .exe file. Alternatively, you can put Wolfram.NETLink.dll in a subdirectory of the application's directory, according to the standard rules for how .NET probes for assemblies that are not strong-named.