Assume the following situation: I have a WolframLibrary function which gets as parameter an integer tensor (which is for simplicity of rank 1) and the function should return an integer list through MathLink.

My question is about the used types in this function only. The start of such a function could look like the following, where I use WolframLibrary functions declared in WolframLibrary.h

EXTERN_C DLLEXPORT mint func( WolframLibraryData lib, mint argc, 
                              MArgument *args, MArgument return_value)
  MTensor tensor_u0 = MArgument_getMTensor(args[0]);
  mint *u0 = lib->MTensor_getIntegerData(tensor_u0);    
  // ...

The full declaration of the last function is

mint* (*MTensor_getIntegerData)( MTensor);

The array u0 contains the linear data of our tensor. Let's say I worked with this array, I used consistently mint in all procedures and I want to send now the mint *result array back through MathLink.

In the MathLink API we have several functions for sending integer lists

int MLPutInteger16List(MLINK link, short *a,int n)
int MLPutInteger32List(MLINK link, int *a,int n)
int MLPutInteger64List(MLINK link, mlint64 *a, int n)

Usually you just use MLPutIntegerList which uses the integer type of the machine. Unfortunately, since version 9 the MathLink integer type and the WolframLibrary integer type differ on my machine.

Additionally, the types used in MathLink seem to be completely unrelated to the WolframLibrary types. While I can use the types in a pure WolframLibrary function consistently and hopefully portable, mixing those two technologies seems not possible easily.

What I would have to do is to look up the underlying type of mint, which is long on my machine here, but int on the Windows machine of my colleague and probably long long on our Windows 7 64bit box. After that I can select the appropriate MLPut... function for my special system. This is not portable and I basically have to repeat all system-dependent #ifdefs which are already there in mathlink.h and friends.

Question: What am I missing here? There must be a portable and consistent way to cast both types.

  • $\begingroup$ @ToddGayley In case you missed this question. Some insight or corrections would be highly appreciated. $\endgroup$
    – halirutan
    Feb 10, 2013 at 2:16
  • $\begingroup$ Just an idea without much thought put into it (sorry if I overlooked something): if you're using C++, create a single overloaded function that calls MLPutInteger16List, MLPutInteger32List or MLPutInteger64List depending on the type of arguments, then use this function. The compiler will figure out which version of the overloaded function to call when you pass it a mint *, and you won't need to think about it as a user or disambiguate with lots of #defines and #ifdefs and anticipating various types ... $\endgroup$
    – Szabolcs
    Feb 13, 2013 at 21:45

1 Answer 1


What you observed is a bit unfortunate because these libraries should be easy to use together (because they're meant to be used together).

Here's a "workaround" that could make your life easier in certain cases. You can use C++ instead of C and take advantage of overloaded functions. I have a header called mlp.h with the following:

#include <mathlink.h>

inline int mlpPutIntegerList(MLINK link, short *a, int n) {
    return MLPutInteger16List(link, a, n);

inline int mlpPutIntegerList(MLINK link, int *a, int n) {
    return MLPutInteger32List(link, a, n);

inline int mlpPutIntegerList(MLINK link, mlint64 *a, int n) {
    return MLPutInteger64List(link, a, n);

// ... similar overloaded versions for other MLPut* functions.
// might need some for long long or compiler specific types too

Then instead of calling one of the MLPutIntegerList functions explicitly, call mlpPutIntegerList:

mint *u0 = ...
mlpPutIntegerList(link, u0, count);

For as long as you can be sure that mint is one of short, int, or long, the compiler will figure out the correct overload to call, and you can use the same source code on all platforms.

One situation where this may potentially go wrong is if mint is not a standard integer type but something else (e.g. a struct). I don't believe that this can be the case, but theoretically it's possible. For example, mlint64 is a struct on 32-bit platforms.

I have used this approach to connect MathLink with another library where the other library has a custom integer type that had different sizes (and different underlying types) on various platforms.

Also, this takes some work, but it's cleaner than using many #ifdefs and it's also more easily re-usable across projects.

  • $\begingroup$ Of course +1 for this nice answer. I probably prefer a C++ template solution because all code is generated at compile time and has no overhead when using it, but your overloading version is maybe easier to understand. Honestly I was hoping for an answer of someone from WRI to understand how it meant to be used ;-) $\endgroup$
    – halirutan
    Feb 17, 2013 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.