MathGroup Archive 2006

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

Search the Archive

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


  • Prev by Date: Re: structure array equivalent in Mathematica
  • Next by Date: Calculating the null space of a matrix with univariate polynomial entries?
  • Previous by thread: Re: Using Mathlink to export arrays
  • Next by thread: Hiding Kernel into taskbar