Re: Using Mathlink to export arrays
- To: mathgroup at smc.vnet.net
- Subject: [mg67138] Re: Using Mathlink to export arrays
- From: "ragfield" <ragfield at gmail.com>
- Date: Sat, 10 Jun 2006 04:53:43 -0400 (EDT)
- References: <e6b4ve$cn5$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
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