3
$\begingroup$

So this may come down to me not being a very competent programmer but I am struggling with passing list from Mathematica via MathLink that aren't of integers. The final code I am hoping to get out of this will pass a list of values to a C++ function I have written and return a different list of values. I decided to learn slowly using the examples given in the Wolfram documentation center. I was able to write a simple function that received a list of integers...did some math on it...and returned a different list of integers. This worked great. If I tried to do this with a list of real values I kept getting a linker error. To simply things I removed the returning of a list of values and just decided to use the list as input and return a value. This resulted in the same linker error. I used the addtwo code from the MathLink examples supplied by Wolfram. The relevant portion of the code is:

#include "mathlink.h"
extern int sumlist(int *a, long alen);

int tot = 0;

int sumlist(int *a, long alen)
{   
        for(int i = 0;i<alen;i++)
        {
            tot = a[i] + tot;       
        }   
        return tot; 
}

with a template file (*.tm)

:Begin:
:Function:       sumlist
:Pattern:        SumList[a_List]
:Arguments:      {a}
:ArgumentTypes:  {IntegerList}
:ReturnType:     Integer
:End:

This code works great and gives me my desired result. Now if instead I wish to pass a list of Real numbers as in the following.

#include "mathlink.h"
extern double sumlist(double *a, long alen);

double tot = 0.0;

double sumlist(double *a, long alen)
{   
        for(int i = 0;i<alen;i++)
        {
            tot = a[i] + tot;       
        }   
        return tot; 
}

with a template file

:Begin:
:Function:       sumlist
:Pattern:        SumList[a_List]
:Arguments:      {a}
:ArgumentTypes:  {Real32List}
:ReturnType:     Real32
:End:

I am following the directions for the Command Line compiling for Microsoft visual studio from this page. I am using Microsoft visual studio 2013(which may be the problem as it technically isn't supported yet)

Everything is fine until I run:

Link sumlist.obj sumlisttm.obj ml32i3m.lib /OUT:sumlist.exe

Which results in the follow error

sumlisttm.obj : error LNK2019: unresolved external symbol "float __cdecl     sumlist(float *,int)" (?sumlist@@YAMPAMH@Z) referenced in function "int __cdecl     _tr0(struct MLink *)"(?_tr0@@YAHPAUMLink@@@Z)
sumlist.exe : fatal error LNK1120: 1 unresolved externals

I have done some testing and determined that I get this error just by trying to pass the list of real values rather than integers regardless of what the function actually does. I have looked for examples of Mathematica/MathLink code and most of them only deal with lists of integers.

$\endgroup$

1 Answer 1

8
$\begingroup$

The problem is that Real32 corresponds to a float (32-bit floating point number), not a double (64 bit floating point number).

The linker error message tells you that it can't find

sumlist(float *, int)

That's because you don't have a function with such a prototype. What you have is

sumlist(double *, long)

which is something different.

Make sure you use matching types. First, use int where int is required (not long), then either change the double to float on the C++ side or alternatively use Real64List and Real64 instead of Real32.

The documentation lists what Mathematica types correspond to what C (or C++) types. It's under "Details".

$\endgroup$
1
  • $\begingroup$ Perfect works now! Thanks for the help. $\endgroup$
    – user573214
    Apr 14, 2014 at 21:57

Your Answer

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

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