Main Site Documentation

Growing values returning from native function


#1

Hi,

I’m having some trouble with understanding exactly how to correctly return values from native functions. I’ve been trying to port a method that I’ve been using in .netmf just as a learning process really (of both the RLPlite process and the C language!), and to see if it’s much faster etc.

It works, and returns the value expected the first time it is called, but then each time after it returns a value that is growing! ???

This is the native code (takes a byte array of a floating point number and returns the float);

int RLP_charArrayToDouble(void *par0, int *par1, unsigned char *par2)
{
	float *num = par0;
	unsigned char *str = par2;
	unsigned int length = par1[0];
	bool decimalFound = false;
	bool preDec = true;
	float preDecimalMulti = (float)1;
	float postDecimalMulti = 0.1;
	float buffer;
	float ret;
	int i = 0;
	
	for(i=0; i<length; i++)
	{
		if (str[i] == 0x2e)
		{
			decimalFound = true;
		}
		else if (str[i] != 0x2e)
		{
			if (decimalFound)
			{
				buffer = (float)(str[i] - '0');
				ret = ret + (buffer * postDecimalMulti);
				postDecimalMulti = postDecimalMulti / (float)10;
			}
			else if (!decimalFound)
			{
				buffer = (float)(str[i] - '0');
				ret = (ret * preDecimalMulti) + buffer;
				if (preDec)
				{
					preDecimalMulti = (float)10;
					preDec = false;
				}
			}
		}
	}
	
	num[0] = ret;
	return ret;
}

and the managed code that calls it (that hopefully explains what it does);

int ret = 0;
byte[] charArrayBytes = new byte[7];
charArrayBytes = Encoding.UTF8.GetBytes("143.617");
int[] length = new int[1];
length[0] = charArrayBytes.Length;
float[] floatReturned = new float[1];
floatReturned[0] = 0;
ret = RLP_ReturnFloatTest.Invoke(floatReturned, length, charArrayBytes);
Debug.Print("'143.617' returned as:" + floatReturned[0].ToString());

The first time I get 143.617 but then 14505.3164, 1450675.12, 145067648, 2147483647! I also have to completely re-program tinybooter and the firmware to reset this! ??? This morning I ran it a few times and it returned the correct value everytime, which in itself is also odd.

I’m a bit stuck now. Should I be disposing of variables or something, or managing them in a different way?

I wondered also if there is an accuracy issue as this always returns 143.617004;

int RLP_ReturnFloatTest(void *par0, int *par1, unsigned char *par2)
{
	float *num = par0;
	
	num[0] = 143.617000;
	
	return 0;
}

Is that a separate issue that is related to the accuracy of the processor?

This is the output from FEZconfig (Cerbuino Bee);

[quote]Loader (TinyBooter) version information:
4.2.6.1 on this computer.
4.2.6.1 on this device.

The Loader (TinyBooter) is up to date. <<<

Firmware (TinyCLR) version information:
4.2.6.2 on this computer.
4.2.6.2 on this device.

The Firmware (TinyCLR) is up to date. <<<[/quote]

Any help is much appreciated. I’m fairly new to all languages and self taught so please be kind! :slight_smile:


#2

OK, I think that I’ve solved it myself. Initialising the float variables ‘buffer’ and ‘ret’ as 0 seems to of sorted it.

I can only assume from that, that these variables are retained in memory somehow and therefore are not 0 when they are initialised the next time the function is called. Does this make sense to anyone?


#3

C/C++ does not initialize variables, but C# does.
On my MedusaMini (Arduino) for example the variable values even persist on a reset.


#4

Thanks.

I guess it’s a bit of a school boy error then. :-[ That’s OK, it’s all part of the learning process.