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: [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


  • Prev by Date: Re: Using Mathlink to export arrays
  • Next by Date: Re: WITM - A web interface to Mathematica
  • Previous by thread: Re: Using Mathlink to export arrays
  • Next by thread: Re: Using Mathlink to export arrays