Re: Using Mathlink to export arrays
- To: mathgroup at smc.vnet.net
- Subject: [mg67222] Re: Using Mathlink to export arrays
- From: "Amy" <amy.squillacote at kitware.com>
- Date: Tue, 13 Jun 2006 01:07:12 -0400 (EDT)
- References: <e6b4ve$cn5$1@smc.vnet.net><e6e25g$1t8$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
ragfield wrote: > Amy wrote: > > I am using Mathlink to move arrays with depth=3 from Mathematica > > (version 5.2) into a C++ program I am developing. I want to represent > > the data in my program as fully as possible (i.e., avoid casting to > > another data type), but I also don't want to use more memory than is > > necessary to store the data. My program handles arrays of any type of > > integer data (short integer, integer, and long integer) as well > > floating-point data (stored as float, not double, in C++). I am trying > > to figure out how to determine from Mathematica what type (and which > > MLGet***Array method) I should use based on the data array coming from > > Mathematica. > > ... > > > I thought if I passed in floating-point data that the > > MLGet***IntegerArray methods would return 0 (for failure), but they did > > not. Instead the MLGetShortIntegerArray method was used, and the > > floating-point data in the array was cast to a short integer type. > > > MathLink converts types automatically for your convenience (e.g. if an > Integer is on the link and you call MLGetDouble(), it will convert the > int to a double). If you want to handle different types yourself you > need to check the type before calling MLGet*(). This is fairly tricky > for arrays. There might be other ways to do this, but here is a way > that works. > > If you're expecting an array, verify this with: > > if(MLGetRawType(theLink) == MLTK_ARRAY) > ... > > Get the depth and copy the heads onto a separate link: > > MLINK theHeadsLink = MLLoopbackOpen(theEnvironment, NULL); > array_meterp theMeter; > long theDepth; > mlapi_token theType; > > if(MLGetArrayType0(theLink, theHeadsLink, &theMeter, &theDepth, > &theType)) > ... > > Use the loopback link containing the heads to determine the dimensions: > > long* theTotal = 1; > long* theDimensions = (long*) malloc(sizeof(long) * theDepth); > for(long i = 0; i < depth; i++) > { > long theDim; > if(MLCheckFunction(theHeadsLink, "List", &theDim)) > { > theDimensions[i] = dim; > theTotal *= dim; > } > else > ; //error > } > > Determine what type of data the array contains > > switch(MLGetRawType(theLink)) > { > case MLTK_CUCHAR: > ... > break; > case MLTK_CSHORT: > ... > break; > case MLTK_CINT: > ... > break; > case MLTK_CFLOAT: > ... > break; > default: // etc > case MLTK_CDOUBLE: > ... > break; > } > > Get the actual Data: > > float* theData = (float*) malloc(sizeof(float) * theTotal); > if(MLGetFloatArrayData(theLink, theMeter, theData, theTotal)) > ... > > Clean up: > > free(theData); > free(theDimensions); > MLReleaseGetArrayState0(theLink, theHeadsLink, theMeter); > MLClose(theHeadsLink); > > -Rob Thanks Rob! That's what I was looking for. - Amy