WSTP Development in C (Windows)

This document describes how to compile and run Wolfram Symbolic Transfer Protocol (WSTP) programs written in the C language on computers running a Microsoft Windows operating system. ("WSTP and External Program Communication" describes how to write WSTP programs in both the Wolfram Language and the C language.) This document also describes how WSTP is implemented for Windows.

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 or generally how to use a Windows-based computer. It is assumed that you have at least worked through the tutorial introduction that came with your set of tools. If you have any trouble building or running your WSTP programs, see the "Troubleshooting" section at the end of this document.

Most of what is described in this document is Windows specific. To learn how to compile and run WSTP programs for another platform, see the Developer Guide for that platform.

Overview

WSTP is implemented as a collection of dynamically linked, shared libraries. When a WSTP program is launched, the main shared library is found in a standard place on disk, loaded by the operating system, and bound to the client WSTP program so that calls to WSTP functions are directed to code within the shared library. On a computer running a 32-bit Windows operating system (2000, XP, Vista), the main shared library is called wstp32i4.dll.

On 64-bit Windows platforms (XP 64, Server 2003, Vista 64, Windows 7, Windows 8), the main shared library for 64-bit WSTP programs is wstp64i4.dll.

An import library (a .lib file) is used when a WSTP program is built. This import library is added to a project file or included in the link command in a makefile. (This import library contains no code; it simply exports the same function names as the shared library in order to satisfy the linker.)

The C interface to WSTP is specified in the header file wstp.h. This file is included in any C or C++ source files that call functions in the WSTP shared library.

The WSTP shared library wstp32i4.dll or wstp64i4.dll is needed at the time a WSTP program is run and needs to be placed where the Windows operating system can find it. The import library and header file are needed at the time a WSTP program is built and need to be placed where your compiler and linker can find them. The installation and use of these components and others are described in more detail below.

Supported Development Platforms

As a shared library, WSTP can be used with any development environment that adheres to the standard calling conventions and binary interface for DLLs specified by Microsoft. However, this document only describes how to build C programs that use WSTP using the Microsoft C++ development environment.

Each development environment supports the notion of a "project document" whereby source files and options for the compiler, linker, and debugger are managed using a project window, a collection of dialog boxes, and other interactive interface elements. In addition to this integrated development environment (IDE), all the vendors supply tools that can be run from the command prompt or invoked by a make utility.

Installing the WSTP Components

This section describes how to install the components from the WSTP Developer Kit so that you can build and run WSTP programs. The WSTP Developer Kit is copied to your hard disk when you install the Wolfram System.

The following instructions assume that the WSTP Developer Kits for Windows have been installed in the location C:\Program Files\Wolfram Research\Mathematica\11.0\SystemFiles\Links\WSTP\DeveloperKit\ by the Wolfram System installer. For Windows there are normally two Developer Kits installed, one for 32-bit Windows platforms, in a folder named Windows, and one for 64-bit Windows platforms, in a folder named Windows-x86-64. If you have received a Developer Kit as a component separate from the Wolfram System, copy the folder Windows or Windows-x86-64 to your hard drive, for example to C:\WSTP. In this case, you will need to modify the following installation instructions to reflect the location of your Developer Kit.

Recommended Installation

SystemAdditions Installation for All Compilers

As of Version 10.0 of the Wolfram System, the Wolfram System installer no longer installs the WSTP dynamic libraries in the Windows system directory. As a WSTP developer, you will need to place the WSTP dlls in a location on your system where your applications can find the dlls.

Connect with the (WebLink[Microsoft Developer Network, http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs .85).aspx]) to learn how Microsoft's operating systems search for program dlls when a program starts.

CompilerAdditions Installation for Microsoft Compilers

Visual Studio 2012

Note that the following instructions assume that you have installed Microsoft's Visual Studio 2012 in the directory C:\Program Files\Microsoft Visual Studio 11\VC. This is the default directory for V11.0 of the Developer Studio. For 64-bit Windows systems, you will find the default Visual Studio installation in C:\Program Files (x86)\Microsoft Visual Studio 11\VC.

explorer "C:\Program Files\Wolfram Research\Mathematica\11.0\SystemFiles\Links\WSTP\DeveloperKit\Windows\CompilerAdditions"

Visual Studio 2010

Note that the following instructions assume that you have installed Microsoft's Visual Studio 2010 in the directory C:\Program Files\Microsoft Visual Studio 10\VC. This is the default directory for V10.0 of the Developer Studio. For 64-bit Windows systems, you will find the default Visual Studio installation in C:\Program Files (x86)\Microsoft Visual Studio 10\VC.

explorer "C:\Program Files\Wolfram Research\Mathematica\11.0\SystemFiles\Links\WSTP\DeveloperKit\Windows\CompilerAdditions"

Elements of the WSTP Developer Kit

WSTP is a layered software system consisting of components that are independent of the operating system and components that make direct use of the communication mechanisms provided by the operating system.

The primary role of the system-independent component is to encode expressions as a string of bytes. This software is implemented in the shared library called wstp32i4.dll (for 32-bit programs) and in wstp64i4.dll (for 64-bit programs). The role of the OS-specific component is to transfer the bytes from one program to another. There may be several implementations of this service. Each implementation is called a WSTP device.

WSTP Shared Libraries and Header Files

The following is a description of each file or directory in the WSTP Developer Kit for Windows. See the section "Recommended Installation" to install these components.

The WSTP Developer Kit for 64-bit Windows platform has a similar set of files, with the main difference appearing in the file names of the components. Where 32-bit Windows components contain a 32 in the component file name, 64-bit versions contain a 64 in the component file name.

SystemAdditions Directory

The files in the SystemAdditions directory are shared libraries that implement WSTP, and are usually installed into a place where the system can find them whenever WSTP programs are executed. (See the section "Recommended Installation" to install these components.) The shared libraries needed by most WSTP programs are at the top level of this directory. These file for 32-bit Windows is wstp32i4.dll. The file for 64-bit Windows is wstp64i4.dll.

wstp32i4.dll/wstp64i4.dll

wstp32i4.dll or wstp64i4.dll is the shared library used by 32-bit WSTP Windows programs (64-bit WSTP Windows programs use wstp64i4.dll) that implements Interface 4 of the WSTP application programming interface (API). It should be placed where the operating system's loader will find it when your 32-bit WSTP program is run. (It is not needed to build 32-bit WSTP programs—only to run them.) You could place this file next to your built WSTP program, or in the Windows system directory, or someplace on your PATH. See the following discussion for more information and alternative installation options.

The WSTP Devices

All the WSTP devices follow a naming scheme that describes what protocol they implement and what types of programs may use them.

SharedMemory Device

SharedMemory is a WSTP device that uses the Win32 memory-mapped file mechanism to transfer data between processes. In Wolfram System 10.0, it is the default device for local connections.

For example, a C program that executes

char* argv[] = {"-linkname", "foo", "-linkprotocol", "SharedMemory", "-linkmode", "connect"};
link = WSOpenArgv( stdenv, argv, argv + 6, 0);

will connect to a Wolfram Language program that evaluates

LinkOpen["foo", LinkProtocol->"SharedMemory", LinkMode->Listen]

TCPIP Device

In Wolfram System 10.0, the TCPIP device is the preferred device for remote connections.

For example, a C program that executes

char* argv[] = {"-linkname", "6000", "-linkprotocol", "TCPIP", "-linkmode", "connect"};
link = WSOpenArgv( stdenv, argv, argv + 6, 0);

will connect to a Wolfram Language program that evaluates

LinkOpen["6000", LinkProtocol->"TCPIP", LinkMode->Listen]

(RefLink[LinkProtocol, paclet:ref/LinkProtocol])->"TCPIP" can be used to connect WSTP programs running on different computers on a network.

IntraProcess Device

IntraProcess is a WSTP device designed for use between threads in the same process. Use this device when you need a full duplex WSTP connection to another thread in your same process.

For example, a C program that executes

char* argv[] = {"-linkname", "abcdef_ipq", "-linkprotocol", "IntraProcess", "-linkmode", "connect"};
link = WSOpenArgv(stdenv, argv, argv + 6, 0);

will connect to another thread that executes

char *argv[] = {"-linkname", "abcdef_ipq", "-linkprotocol", "IntraProcess", "-linkmode", "listen"};
link = WSOpenArgv(stdenv, argv, argv + 6, 0);

IntraProcess cannot be used to connect to a link running in a separate process.

FileMap Device

The FileMap device is an obsolete LinkProtocol available only on Windows.

For example, a C program that executes

char* argv[] = {"-linkname", "foo", "-linkprotocol", "FileMap", "-linkmode", "connect"};
link = WSOpenArgv( stdenv, argv, argv + 6, 0);

will connect to a Wolfram Language program that evaluates

LinkOpen["foo", LinkProtocol->"FileMap", LinkMode->Listen]

These devices are used by default by WSTP programs when no (RefLink[LinkProtocol, paclet:ref/LinkProtocol]) is specified.

64-bit Windows does not support the "FileMap" protocol.

TCP Device

The TCP device is an obsolete LinkProtocol that uses the services of the TCP internet protocol to transfer data between processes.

For example, a C program that executes

char* argv[] = {"-linkname", "6000", "-linkprotocol", "TCP", "-linkmode", "connect"};
link = WSOpenArgv( stdenv, argv, argv + 6, 0);

will connect to a Wolfram Language program that evaluates

LinkOpen["6000", LinkProtocol->"TCP", LinkMode->Listen]

The "TCP" (RefLink[LinkProtocol, paclet:ref/LinkProtocol]) can be used to connect WSTP programs running on different computers on a network.

The "TCP" (RefLink[LinkProtocol, paclet:ref/LinkProtocol]) was deprecated in Mathematica 5.1 and only continues to exist for backward compatibility. Users of "TCP" should convert their code to use "TCPIP".

CompilerAdditions Directory

Visual Studio 2012

CompilerAdditions\wstp.h

wstp.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 place this header file in the same directory as your source files that include it, or in the same location as the standard header files provided with your development tools. Alternatively, you could add the location of wstp.h to the search path for header files. (This is typically done using command line switches, an environment variable, or a setting in a dialog box.)

CompilerAdditions\wstp*i*.lib

The *.lib files are import libraries that your linker would use to resolve references in your code to functions in the WSTP shared library. One of these .lib files would be referenced in your project file, makefile, or link command line. Because the format of an import library is not standardized, one import library is supplied for each of the most popular development environments.

wstp32i4m.lib or wstp64i4m.lib is the import library for use with the Microsoft C/C++ development tools including Microsoft Visual Studio. (It is a COFF import library created by the Microsoft linker.) This file should be placed where it will be found by the Microsoft linker. To avoid having to specify a path, place this file in your C:\Program Files\Microsoft Visual Studio 11\VC\PlatformSDK\lib directory. Place the 64-bit .lib file in your C:\Program Files\Microsoft Visual Studio 11\VC\PlatformSDK\lib\AMD64 directory.

CompilerAdditions\wsprep.exe

(RefLink[wsprep.exe, paclet:ref/program/wsprep]) is a 32-bit console program that writes WSTP programs automatically by processing "template" files. It may be convenient to place this file in the Bin directory of your development tools. On 64-bit Windows, (RefLink[wsprep.exe, paclet:ref/program/wsprep]) is a 64-bit console program.

Visual Studio 2010

CompilerAdditions\wstp.h

wstp.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 place this header file in the same directory as your source files that include it, or in the same location as the standard header files provided with your development tools. Alternatively, you could add the location of wstp.h to the search path for header files. (This is typically done using command line switches, an environment variable, or a setting in a dialog box.)

CompilerAdditions\wstp*i*.lib

The *.lib files are import libraries that your linker would use to resolve references in your code to functions in the WSTP shared library. One of these .lib files would be referenced in your project file, makefile, or link command line. Because the format of an import library is not standardized, one import library is supplied for each of the most popular development environments.

wstp32i4m.lib or wstp64i4m.lib is the import library for use with the Microsoft C/C++ development tools, including Microsoft Visual Studio. (It is a COFF import library created by the Microsoft linker.) This file should be placed where it will be found by the Microsoft linker. To avoid having to specify a path, place this file in your C:\Program Files\Microsoft Visual Studio 10\VC\PlatformSDK\lib directory. Place the 64-bit .lib file in your C:\Program Files\Microsoft Visual Studio 10\VC\PlatformSDK\lib\AMD64 directory.

CompilerAdditions\wsprep.exe

(RefLink[wsprep.exe, paclet:ref/program/wsprep]) is a 32-bit console program that writes WSTP programs automatically by processing "template" files. It may be convenient to place this file in the Bin directory of your development tools. On 64-bit Windows, (RefLink[wsprep.exe, paclet:ref/program/wsprep]) is a 64-bit console program.

PrebuiltExamples Directory

This folder contains prebuilt versions of the example programs. "Building WSTP Programs" describes how to build them yourself using the source code in the WSTPExamples folder. "Running WSTP Programs" describes how to run these programs.

WSTPExamples Directory

This folder contains the source code for some very simple WSTP programs. By using this source code, you can learn how to build and run WSTP programs without having to write any code yourself.

Alternative Components Directory

DebugLibraries is a copy of WSTPLibraries that does extensive error checking and logs information that may be useful. See the "Troubleshooting" section for a description of how to use this library.

Building WSTP Programs

The general procedure for building WSTP programs is to include wstp.h in any C or C++ source files that make WSTP function calls, to compile your source files, and then to link the resulting object code with the WSTP import library and any other standard libraries required by your application. If your application uses the WSTP template mechanism, then your template files must first be processed into a C source file using (RefLink[wsprep, paclet:ref/program/wsprep]). The details for several popular development environments are provided here.

The build instructions in "Building WSTP Programs with Microsoft Visual Studio" assume you have followed the recommended installation instructions for the WSTP compiler additions. If you have placed the compiler additions elsewhere on your hard disk, you may need to modify the instructions by setting environment variables, specifying additional command line arguments, or specifying full pathnames when referring to the WSTP compiler additions.

WSTP Versioning

As a shared library, each revision of WSTP must maintain compatibility with previous revisions. Yet, at times, new functionality needs to be added. WSTP adopts a simple versioning strategy that can be adapted to many compile-time and runtime environments.

Strategy

WSTP evolves by improving its implementation and by improving its interface. The values of WSREVISION or WSINTERFACE defined in wstp.h are incremented whenever an improvement is made and released.

WSREVISION is the current revision number. It is incremented every time a change is made to the source and WSTP is rebuilt and distributed on any platform. (Bug fixes, optimizations, or other improvements transparent to the interface increment only this number.)

WSINTERFACE is a name for a documented interface to WSTP. This number is incremented whenever a named constant or function is added, removed, or its behavior is changed in a way that could break existing correct client programs. It is expected that the interface to WSTP will be improved over time so that implementations of higher-numbered interfaces are more complete or more convenient to use for writing effective client programs. In particular, a specific interface provides all the useful functionality of an earlier interface.

For Windows, the different interfaces of the WSTP libraries are implemented in different shared libraries. The file wstp32i4.dll contains the implementation of Interface 4 of the latest WSTP revision. You need only keep the latest revision (as shown in the Properties box for the shared library) of these files in your Windows system folder to run any WSTP program.

In addition, each WSTP interface has a separate import library to link against so that developers make a conscious decision as to which interface they require at compile time. So, for example, a developer using Microsoft's Visual Studio who needs functionality that was added for Interface 4 must link with wstp32i4m.lib rather than a library file with a different interface.

Using WSTP Template Files

If your program uses the WSTP template mechanism as described in "WSTP and External Program Communication", you must preprocess your source files that contain template entries using the (RefLink[wsprep, paclet:ref/program/wsprep]) console program. A template entry is a sequence of lines that contain template keywords. (Each entry defines a Wolfram Language function that when evaluated calls an associated C function.) When (RefLink[wsprep, paclet:ref/program/wsprep]) 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 WSTP. The result is a C source file that is ready for compilation.

For example, the command

wsprep 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
  wsprep addtwo.tm -o addtwotm.c

Building WSTP Programs with Microsoft Visual Studio

Using the Command Line Tools

Visual Studio 2012

In order to use the command line tools from a command window, you must run the batch file VCVARSALL.BAT to configure the environment. You can find the file in C:\Program Files\Microsoft Visual Studio 11\VC\VCVARSALL.BAT. Alternatively, you can use the shortcut provided in Start ▶ All Programs ▶ Microsoft Visual Studio 2012 ▶ Visual Studio Tools ▶VS2012 x86 Native Tools Command Prompt. VCVARSALL.BAT takes an argument to indicate which set of compiler tools the environment should use. For 32-bit Windows development use: VCVARSALL.BAT x86. For 64-bit Windows development use: VCVARSALL.BAT amd64. Alternatively, on 64-bit Windows machines you can use the shortcut provided in Start ▶ All Programs ▶ Microsoft Visual Studio 2012 ▶ Visual Studio Tools ▶ VS2012 x64 Cross Tools Command Prompt. VCVARSALL.BAT will correctly configure the PATH, INCLUDE, and LIB environment variables so that you can use the Microsoft Compiler tools from your command line environment.

Building a WSTP Program to Be Called by the Wolfram Language Kernel

To build the addtwo.exe example program:

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows\WSTPExamples\

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\WSTPExamples\

SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /O2 /DNDEBUG
SET LINK=/NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no /PDB:NONE kernel32.lib user32.lib gdi32.lib
WSPREP addtwo.tm -o addtwotm.c
CL addtwo.c addtwotm.c
LINK addtwo.obj addtwotm.obj wstp32i4m.lib /OUT:addtwo.exe

LINK addtwo.obj addtwotm.obj wstp64i4m.lib /OUT:addtwo.exe

Building a WSTP Program That Calls the Wolfram Language Kernel

To build the factor.exe example program:

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd AddOns\WSTP\DeveloperKit\Windows\WSTPExamples\

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\WSTPExamples\

SET CL=/nologo /c /DWIN32 /D_CONSOLE /W3 /O2 /DNDEBUG
SET LINK=/NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:NONE kernel32.lib user32.lib
CL factor.c
LINK factor.obj wstp32i4m.lib /OUT:factor.exe

LINK factor.obj wstp64i4m.lib /OUT:factor.exe

Debugging a WSTP Program Called from the Wolfram Language Kernel

To build a debug version of addtwo.exe:

SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /Z7 /Od /D_DEBUG
SET LINK=/NOLOGO /SUBSYSTEM:windows /DEBUG /PDB:NONE /INCREMENTAL:no kernel32.lib user32.lib gdi32.lib
WSPREP addtwo.tm -o addtwotm.c
CL addtwo.c addtwotm.c
LINK addtwo.obj addtwotm.obj wstp32i4m.lib /OUT:addtwo.exe

LINK addtwo.obj addtwotm.obj wstp64i4m.lib /OUT:addtwo.exe

Debugging a WSTP Program That Calls the Wolfram Language Kernel

To build a debug version of factor.exe:

SET CL=/nologo /c /DWIN32 /D_CONSOLE /W3 /Z7 /Od /D_DEBUG
SET LINK=/NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:NONE /DEBUG kernel32.lib user32.lib
CL factor.c
LINK factor.obj wstp32i4m.lib /OUT:factor.exe

LINK factor.obj wstp64i4m.lib /OUT:factor.exe

To debug factor.exe:

Visual Studio 2010

In order to use the command line tools from a command window, you must run the batch file VCVARSALL.BAT to configure the environment. You can find the file in C:\Program Files\Microsoft Visual Studio 10\VC\VCVARSALL.BAT. Alternatively, you can use the shortcut provided in Start ▶ All Programs ▶ Microsoft Visual Studio 2010 ▶ Visual Studio Tools ▶ Visual Studio Command Prompt (2010). VCVARSALL.BAT takes an argument to indicate which set of compiler tools the environment should use. For 32-bit Windows development use: VCVARSALL.BAT x86. For 64-bit Windows development use: VCVARSALL.BAT amd64. Alternatively, on 64-bit Windows machines you can use the shortcut provided in Start ▶ All Programs ▶ Microsoft Visual Studio 2010 ▶ Visual Studio Tools ▶ Visual Studio x64 Win64 Command Prompt (2010). VCVARSALL.BAT will correctly configure the PATH, INCLUDE, and LIB environment variables so that you can use the Microsoft Compiler tools from your command line environment.

Building a WSTP Program to Be Called by the Wolfram Language Kernel

To build the addtwo.exe example program:

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows\WSTPExamples\

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\WSTPExamples\

SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /O2 /DNDEBUG
SET LINK=/NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no /PDB:NONE kernel32.lib user32.lib gdi32.lib
WSPREP addtwo.tm -o addtwotm.c
CL addtwo.c addtwotm.c
LINK addtwo.obj addtwotm.obj wstp32i4m.lib /OUT:addtwo.exe

LINK addtwo.obj addtwotm.obj wstp64i4m.lib /OUT:addtwo.exe

Building a WSTP Program That Calls the Wolfram Language Kernel

To build the factor.exe example program:

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd AddOns\WSTP\DeveloperKit\Windows\WSTPExamples\

C:
cd "C:\Program Files\Wolfram Research\Mathematica\11.0\"
cd SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\WSTPExamples\

SET CL=/nologo /c /DWIN32 /D_CONSOLE /W3 /O2 /DNDEBUG
SET LINK=/NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:NONE kernel32.lib user32.lib
CL factor.c
LINK factor.obj wstp32i4m.lib /OUT:factor.exe

LINK factor.obj wstp64i4m.lib /OUT:factor.exe

Debugging a WSTP Program Called from the Wolfram Language Kernel

To build a debug version of addtwo.exe:

SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /Z7 /Od /D_DEBUG
SET LINK=/NOLOGO /SUBSYSTEM:windows /DEBUG /PDB:NONE /INCREMENTAL:no kernel32.lib user32.lib gdi32.lib
WSPREP addtwo.tm -o addtwotm.c
CL addtwo.c addtwotm.c
LINK addtwo.obj addtwotm.obj wstp32i4m.lib /OUT:addtwo.exe

LINK addtwo.obj addtwotm.obj wstp64i4m.lib /OUT:addtwo.exe

Debugging a WSTP Program That Calls the Wolfram Language Kernel

To build a debug version of factor.exe:

SET CL=/nologo /c /DWIN32 /D_CONSOLE /W3 /Z7 /Od /D_DEBUG
SET LINK=/NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:NONE /DEBUG kernel32.lib user32.lib
CL factor.c
LINK factor.obj wstp32i4m.lib /OUT:factor.exe

LINK factor.obj wstp64i4m.lib /OUT:factor.exe

To debug factor.exe:

Short Summary of Compiler Switches

Short Summary of Linker Switches

Standard System Libraries

Using the Program Build Utility NMAKE

NMAKE is a utility provided with Microsoft's development tools that manages the process of building programs. NMAKE reads a makefile that describes the dependencies and commands required to build and rebuild one or more programs. NMAKE rebuilds any components that have become out of date when one or more prerequisite files have been updated. This document does not describe NMAKE or makefiles in detail. A simple makefile is provided here that illustrates how the build commands listed above can be automatically executed by simply typing NMAKE at a command prompt. To learn more about NMAKE, its general and powerful mechanisms, and how to use macros or special forms, see the NMAKE Reference in your "Microsoft Visual Studio Guide".

Visual Studio 2012

Using a Makefile to Build a Template Program That Uses the WIN32 API

To build addtwo.exe using the NMAKE utility:

# addtwo.mak a makefile for building the addtwo.exe example program

CFLAGS = /nologo /c /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_WINDOWS

# Linking against gdi32.lib for access to windowing mechanisms
LFLAGS = /DEBUG /PDB:NONE /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no kernel32.lib user32.lib gdi32.lib

# Uncomment the value below for working on a 64-bit Windows system
# PLATFORM = WIN64
PLATFORM = WIN32

!if "$(PLATFORM)" == "WIN32"
LIBFILE = wstp32i4m.lib
!else
LIBFILE = wstp64i4m.lib
!endif

addtwo.exe : addtwo.obj addtwotm.obj
  LINK addtwo.obj addtwotm.obj $(LIBFILE) /OUT:addtwo.exe @<<
$(LFLAGS)
<<

addtwo.obj : addtwo.c
  CL @<< addtwo.c
$(CFLAGS)
<<

addtwotm.obj : addtwotm.c
  CL @<< addtwotm.c
$(CFLAGS)
<<

# Need to call wsprep to preprocess WSTP template
addtwotm.c : addtwo.tm
  wsprep addtwo.tm -o addtwotm.c

NMAKE /f addtwo.mak

Makefiles consist of a collection of build rules, macros, and other special forms.

A build rule consists of a target file, followed by a colon, followed by a list of the target's prerequisite files (which must either exist or can be built by other build rules in the makefile), followed by one or more indented lines containing the commands required to build the target from its prerequisites. For example, the makefile above states that the file addtwotm.c depends on addtwo.tm and should be rebuilt any time addtwo.tm is modified. The build command wsprep addtwo.tm -o addtwotm.c is used to rebuild the target addtwotm.c.

Macros are named strings of text that can be inserted into the makefile using the notation  $(name). For example, in this makefile, $(CFLAGS) is expanded by NMAKE wherever it appears into the string /nologo /c /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_WINDOWS.

You might expect that the command to compile addtwo.c would appear in the makefile simply as CL $(CFLAGS) addtwo.c. However, it would then be possible for you to edit the definition of CFLAGS so that the resulting compiler command exceeded the maximum allowable length of a command line. Because command lines are restricted in length, command line tools often provide a mechanism to read command line arguments from so-called response files. The syntax is generally @responsefile. This mechanism is used above, along with NMAKE's ability to produce temporary files using the following special form.

<<

text to put in temporary file

<<

Using a Makefile to Build a Console Program

To build factor.exe using the NMAKE utility:

# factor.mak a makefile for building the factor.exe example program
# This makefile builds a console program

CFLAGS = /nologo /c /MLd /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_CONSOLE
LFLAGS = /DEBUG /PDB:NONE /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no kernel32.lib user32.lib

# Uncomment the value below for working on a 64-bit Windows system
# PLATFORM = WIN64
PLATFORM = WIN32

!if "$(PLATFORM)" == "WIN32"
LIBFILE = wstp32i4m.lib
!else
LIBFILE = wstp64i4m.lib
!endif

factor.exe : factor.obj
  LINK factor.obj $(LIBFILE) /OUT:factor.exe @<<
$(LFLAGS)
<<

factor.obj : factor.c
  CL @<< factor.c
$(CFLAGS)
<<

NMAKE /f factor.mak

Visual Studio 2010

Using a Makefile to Build a Template Program That Uses the WIN32 API

To build addtwo.exe using the NMAKE utility:

# addtwo.mak a makefile for building the addtwo.exe example program

CFLAGS = /nologo /c /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_WINDOWS

# Linking against gdi32.lib for access to windowing mechanisms
LFLAGS = /DEBUG /PDB:NONE /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no kernel32.lib user32.lib gdi32.lib

# Uncomment the value below for working on a 64-bit Windows system
# PLATFORM = WIN64
PLATFORM = WIN32

!if "$(PLATFORM)" == "WIN32"
LIBFILE = wstp32i4m.lib
!else
LIBFILE = wstp64i4m.lib
!endif

addtwo.exe : addtwo.obj addtwotm.obj
  LINK addtwo.obj addtwotm.obj $(LIBFILE) /OUT:addtwo.exe @<<
$(LFLAGS)
<<

addtwo.obj : addtwo.c
  CL @<< addtwo.c
$(CFLAGS)
<<

addtwotm.obj : addtwotm.c
  CL @<< addtwotm.c
$(CFLAGS)
<<

# Need to call wsprep to preprocess WSTP template
addtwotm.c : addtwo.tm
  wsprep addtwo.tm -o addtwotm.c

NMAKE /f addtwo.mak

Makefiles consist of a collection of build rules, macros, and other special forms.

A build rule consists of a target file, followed by a colon, followed by a list of the target's prerequisite files (which must either exist or can be built by other build rules in the makefile), followed by one or more indented lines containing the commands required to build the target from its prerequisites. For example, the makefile above states that the file addtwotm.c depends on addtwo.tm and should be rebuilt any time addtwo.tm is modified. The build command wsprep addtwo.tm -o addtwotm.c is used to rebuild the target addtwotm.c.

Macros are named strings of text that can be inserted into the makefile using the notation  $(name). For example, in this makefile, $(CFLAGS) is expanded by NMAKE wherever it appears into the string /nologo /c /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_WINDOWS.

You might expect that the command to compile addtwo.c would appear in the makefile simply as CL $(CFLAGS) addtwo.c. However, it would then be possible for you to edit the definition of CFLAGS so that the resulting compiler command exceeded the maximum allowable length of a command line. Because command lines are restricted in length, command line tools often provide a mechanism to read command line arguments from so-called response files. The syntax is generally @responsefile. This mechanism is used above, along with NMAKE's ability to produce temporary files using the following special form.

<<

text to put in temporary file

<<

Using a Makefile to Build a Console Program

To build factor.exe using the NMAKE utility:

# factor.mak a makefile for building the factor.exe example program
# This makefile builds a console program

CFLAGS = /nologo /c /MLd /W3 /Z7 /Od /DWIN32 /D_DEBUG /D_CONSOLE
LFLAGS = /DEBUG /PDB:NONE /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no kernel32.lib user32.lib

# Uncomment the value below for working on a 64-bit Windows system
# PLATFORM = WIN64
PLATFORM = WIN32

!if "$(PLATFORM)" == "WIN32"
LIBFILE = wstp32i4m.lib
!else
LIBFILE = wstp64i4m.lib
!endif

factor.exe : factor.obj
  LINK factor.obj $(LIBFILE) /OUT:factor.exe @<<
$(LFLAGS)
<<

factor.obj : factor.c
  CL @<< factor.c
$(CFLAGS)
<<

NMAKE /f factor.mak

Using the Integrated Development Environment Visual Studio 2012

Steps Common to All Projects

Steps required to use WSTP with Microsoft Visual Studio 2012:

Creating a Project for addtwo.exe

To create a project solution that can be used to edit, build, and debug addtwo.exe:

1>------ Build started: Project: addtwo, Configuration: Debug x64 ------
1>  addtwo.c
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
1>c:\users\steve\documents\visual studio 2012\Projects\addtwo\x64\Debug\addtwo.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#if WINDOWS_WSTP

#if 0 && WINDOWS_WSTP

Creating a Project for factor.exe

To create a project solution that can be used to edit, build, and debug factor.exe:

Using the Integrated Development Environment Visual Studio 2010

Steps Common to All Projects

Steps required to use WSTP with Microsoft Visual Studio 2010:

Creating a Project for addtwo.exe

To create a project solution that can be used to edit, build, and debug addtwo.exe:

Creating a Project for factor.exe

To create a project solution that can be used to edit, build, and debug factor.exe:

Running WSTP Programs

The instructions in "Building WSTP Programs" describe how to build two WSTP programs using source code in the WSTPExamples directory. These two programs, addtwo.exe and factor.exe, 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 WSTP system additions are installed and working and to learn what to expect from these examples when they are properly built.

After trying out the two examples, you should read the following subsections to learn about other issues you will confront running WSTP programs on a Windows computer.

There are two basic types of WSTP 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 the Wolfram Language must run the (RefLink[Install, paclet:ref/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 to communicate only 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 the work of creating and managing their own links. In addition to the factor example, the Wolfram System front end and the Wolfram Language kernel are also examples 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 Wolfram Language Kernel

The first example program, addtwo, is a WSTP template program that is installed into the Wolfram System. That is, this program runs in the background, providing, as a service to the Wolfram Language, one or more externally compiled functions. To the Wolfram Language user, these functions appear to be built-in. The addtwo program uses a template file that defines the Wolfram Language function AddTwo[] as a call to the C function addtwo(). (The template mechanism is described in "Setting Up External Functions to Be Called from the Wolfram System".) The source code for this program looks like 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 __stdcall WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{
	char  buff[512];
	char FAR * buff_start = buff;
	char FAR * argv[32];
	char FAR * FAR * argv_end = argv + 32;

	if( !WSInitializeIcon( hinstCurrent, nCmdShow)) return 1;
	WSScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
	return WSMain( argv_end - argv, argv);
}

Evaluate the following two cells:

SetDirectory[$InstallationDirectory<>"/SystemFiles/Links/WSTP/DeveloperKit/"<>$SystemID<>"/PrebuiltExamples"]

link = Install["./addtwo"]

To see a list of the newly available functions, evaluate the following cell:

LinkPatterns[link]

This displays the usage message for the AddTwo[] function as defined in the file addtwo.tm:

?AddTwo

Now try it:

AddTwo[2, 3]

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, then 2^15-1 is the largest C int.)

AddTwo[2^31-1, 1]

The AddTwo program is not prepared for big integers:

AddTwo[2^31, 1]

This does not match AddTwo[_Integer, _Integer]:

AddTwo[x, 1]

(RefLink[Install, paclet:ref/Install])[] called (RefLink[LinkOpen, paclet:ref/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:

??AddTwo

When you are finished using the external program, evaluate the following:

Uninstall[link]

Invoking the Wolfram Language Kernel from within a Prebuilt Example

The second example program, factor, is a Wolfram System front end in the sense that the Wolfram Language 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.

This example program, like several of the others, is a console program. That is, rather than presenting a graphical user interface, it interacts with the user in a console window using the standard error, input, and output streams defined by ANSI C. (As you experiment with WSTP, you may find it convenient, initially, to use a console window. This is discussed in detail in the section "Building WSTP Programs".)

To run the example program factor.exe:

factor -linklaunch

Integer to factor: 123456789

Integer to factor: 123456789
3 ^ 2
3607 ^ 1
3803 ^ 1

Supported Link Protocols

WSTP links are opened by the C function (NonWLLink[WSOpenArgcArgv(), paclet:ref/c/WSOpenArgcArgv]) and the Wolfram Language functions (RefLink[LinkCreate, paclet:ref/LinkCreate]), (RefLink[LinkLaunch, paclet:ref/LinkLaunch]), and (RefLink[LinkConnect, paclet:ref/LinkConnect]), each of which accepts an option for specifying a link protocol. On 32-bit Windows platforms, the legal values for the (RefLink[LinkProtocol, paclet:ref/LinkProtocol]) option are "SharedMemory", "TCPIP", "FileMap", "TCP", and "IntraProcess". On 64-bit Windows platforms, the legal values for the (RefLink[LinkProtocol, paclet:ref/LinkProtocol]) option are "SharedMemory", "TCPIP", "TCP", and "IntraProcess". A link protocol is the mechanism used to transport data from one end of a connection to the other. The default is "SharedMemory" for all link modes except LoopBack.

Note that the "FileMap" and "SharedMemory" protocols allow link names to be arbitrary words with 31 or fewer characters, while link names are often unsigned 16-bit integers for the "TCPIP" and "TCP" protocols. Even though "TCPIP" and "TCP" link names are integers, they are still given as strings (of digits) to (NonWLLink[WSOpenArgcArgv(), paclet:ref/c/WSOpenArgcArgv]) and (RefLink[LinkOpen, paclet:ref/LinkOpen])[].

Note that for LinkMode->Launch, the link name is not just a pathname to a file to launch, but a command line with space-separated arguments. Hence, spaces in filenames need to be properly quoted. For example,

LinkOpen[ "My Prog.exe"] (*wrong!*)

would try to launch the program "My" with command line argument of "Prog.exe". Whereas

LinkOpen[ "\"My Prog.exe\""]

would launch "My Prog.exe".

Troubleshooting