MathGroup Archive 2001

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Help With MathLink

  • To: mathgroup at smc.vnet.net
  • Subject: [mg28956] Re: Help With MathLink
  • From: tgayley at wolfram.com (Todd Gayley)
  • Date: Wed, 23 May 2001 01:54:25 -0400 (EDT)
  • Organization: Wolfram Research, Inc.
  • References: <9ea6i5$4sq@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

On 21 May 2001 00:45:57 -0400, "Ersek, Ted R" <ErsekTR at navair.navy.mil> wrote:

>You may remember the RootSearch program I discussed several weeks ago. So
>far I only had a little time to work on it .... I want to do most of the
>work in C and I am having trouble with MathLink.  I will make the program
>more elegant once I get it working.
>
>In the Mathematica I define:
>
>In[1]:=
>    f = Sin; (* Eventually Rootsearch will automatically define f in a
>privat context. *)
>    SampleFunction[x_]:= With[ {y=N[f[x]] },
>      If[ MachineNumberQ[y], {x, y, 1.0}, {x, 99.0, 0.0} ]
>    ]
>
>(*************************)
>Then I get the following results:
>
>In[2]:= Install[ "rootsearch" ]
>
>Out[2]=
>    LinkObject[.\rootsearch.exe,2,2]
>
>
>In[3]:=  RootSearch[ Sin[x], {x, 2.0, 3.0}]
>
>Out[3]=
>   {{0. , 0. , 0. }, {0. , 0. , 0. }}
>
>I expected the following output instead.
>   {{2., 0.909297, 1. },{3., 0.14112, 1. }}
>
>
>Please help me get it working.  I can email you the related files if it
>helps. 
>    Thank you in advance,
>    Ted Ersek
>----------------------------------
>
>My MathLink templete is:
>/* ----------------------- */
>:Begin:
>:Function:       root_search
>:Pattern:        RootSearch[func_,{x_Symbol,x0_Real,x1_Real}]
>
>:Arguments:      { x0, x1}
>:ArgumentTypes:  { Real, Real }
>:ReturnType:     Manual
>:End:
>/* ------------------------- */
>
>My source code is:
>
>/* ------------------------- */
>
>#include "mathlink.h"
>#include "stdlib.h"
>#include "stdio.h"
> 
>void sample_function( double x, double *result);
>
>extern void root_search(double x0, double x1);
>
>void root_search(double x0, double x1)
>{
>  int total_samples=0;
>  int dimensions[2];
>  char *heads[2];
>  long depth=2;
>  double *value_array;
>  value_array=(double*)calloc(24,sizeof(double));
>
>  sample_function(x0,value_array);
>  total_samples++;
>
>  sample_function(x1,value_array+3);
>  total_samples++;
>
>  dimensions[0]=2;
>  dimensions[1]=3;
>  heads[0]=heads[1]="List"; 
>  MLPutRealArray(stdlink,value_array,dimensions,heads,depth);
>  return;
>}
>
> 
>void sample_function( double x, double *result )
>{
>  long three=3;
>  
>  MLPutFunction(stdlink,"EvaluatePacket",1);
>    MLPutFunction(stdlink,"SampleFunction",1);
>      MLPutDouble(stdlink,x);
>  MLEndPacket(stdlink);
>  MLNextPacket(stdlink);
>  
>  MLGetRealList(stdlink,&result,&three);
>  MLDisownRealList(stdlink,result,three);
>  return;
>}
>
>
>

Ted,

The problem is that MLGetRealList does not copy any array data into a buffer for you. Your
code is written with that expectation. MLGetRealList (and the other array-getting
functions) only give you a pointer to a buffer of array data down inside MathLink. You
have to copy that data yourself.

You need to write sample_function like this:

void sample_function( double x, double *result )
{
  // No point in any assignment here. MathLink writes into this value; it
  // does not read it
  long three;
  
  double* arrayData;

  MLPutFunction(stdlink,"EvaluatePacket",1);
    MLPutFunction(stdlink,"SampleFunction",1);
      MLPutDouble(stdlink,x);
  MLEndPacket(stdlink);
  MLNextPacket(stdlink);
  
  MLGetRealList(stdlink,&arrayData,&three);
  memcpy(result, arrayData, three * sizeof(double));
  MLDisownRealList(stdlink,arrayData,three);
  return;
}


Finally, note that if MLGetRealList actually did copy three doubles into your &result
argument, your program would crash, as you would be blowing away data on the stack, not
writing into the buffer that you had earlier allocated. Aren't pointers fun?


--Todd Gayley
Wolfram Research


  • Prev by Date: RE: Hiding data in Cells?
  • Next by Date: RE: Speed up ListPlot3D
  • Previous by thread: Help With MathLink
  • Next by thread: MathGL3D: Keep axis when exporting to VRML ?