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