function pointer & memory selection

Thanks for your explanation of the void* pointer thing :slight_smile:

i have used this and managed to get the most things working.

know i have a conceptual problem -

i have a mapping to parse the value from an incoming string (char array)
for this function i also want to use a function pointer -
its the same way as for the other function pointer...
but at the moment this functions are returning different data types -
so the compiler complains about he can not assign the pointer - ok
thats clear -
but how to handle this?
i 'think' i need a return type that is different for each function...
i tested - i cant return a pointer to an internal variable of the called function - thats also clear -
if the function exits the pointer losses his destination.
i could use a in the calling function declared variable and give the parsing function a pointer to this-
so it could write the parsed value to this outside location..
but for this i have to declare a variable - and it needs a type -
so at the moment i can use the biggest used type (for me currently uint16_t)

here is the interessting part of the code...
(the complete test_functionpointer.ino is in the attachment (otherwise the forum message would be to big..)

//.....

// parse
typedef uint16_t (xLocalTestClass::*tCbfunc_parseValue) (char *caValue);
bool _parseValue_Bool(char *caValue) {
	return (bool) atoi(caValue);
};

//....

uint16_t _parseValue_UIntBinary(char *caValue) {
	uint16_t wResult = 0;
	if (strlen(caValue) == 16) {
		byte bCharIndex = 0;
		for (unsigned int mask = 0b1000000000000000; mask; mask >>= 1) {
			// check if this bit is set
			if (caValue[bCharIndex] == '1') {
				// set Bit
				wResult |= mask;
			} // else its 0 so do nothing.
			bCharIndex = bCharIndex + 1;
		}
	}
	return wResult;
};

//.....

// test 
byte test(byte bOperation, char cSwitchMemory, byte bBitIndex, void *pValue, char *caValue) {
	
	// default to left
	byte bLRIndex = 0;
	if ( 1 != 1) {
		// set to right
		bLRIndex = 1;
	}
	
	// pointer to Memory Value
	void *pMemory = NULL;
	
	
	// function pointers
	tCbfunc_CheckChanged fc_CheckChanged = NULL;
	tCbfunc_parseValue fc_parseValue = NULL;
	// tCbfunc_printValue fc_printValue = NULL;
	tCbfunc_setValue fc_setValue = NULL;
	
	switch (cSwitchMemory) {
		case 'a': {
			pMemory = &memory_LeftRight[bLRIndex].wRotaryEncoder_position;
			fc_CheckChanged	= &xLocalTestClass::_checkChanged_UInt;
			fc_setValue		= &xLocalTestClass::_setValue_UInt;
			fc_parseValue	= &xLocalTestClass::_parseValue_UInt;
		} break;
		case 'b': {
			pMemory = &memory_LeftRight[bLRIndex].wLEDsRaw;
			fc_CheckChanged = &xLocalTestClass::_checkChanged_2Bit;
			fc_setValue		= &xLocalTestClass::_setValue_2Bit;
			fc_parseValue	= &xLocalTestClass::_parseValue_UIntBinary;
		} break;
		case 'c': {
			pMemory = &memory_System.bSlidingSwitch_Left;
			fc_CheckChanged = &xLocalTestClass::_checkChanged_UInt;
			fc_setValue		= &xLocalTestClass::_setValue_Bool;
			fc_parseValue	= &xLocalTestClass::_parseValue_Bool;
		} break;
	} // end switch level2
	
	
	// do things with function pointers
	// remember Original Operation
	byte bOperationOld = bOperation;
	// do as long as Operation changes:
	do {
		bOperationOld = bOperation;
		switch (bOperation) {
			case hdOperation_GET: {
				Serial.println(F("hdOperation_GET"));
				*(uint16_t *) pValue = *(uint16_t *) pMemory;
			}
			case hdOperation_RECEIVE: {
				Serial.println(F("hdOperation_RECEIVE"));
				*pValue = (*this.*fc_parseValue)(caValue);
				bOperation = hdOperation_SETINT;
			} break;
			case hdOperation_SETINT:
			case hdOperation_SET: {
				Serial.println(F("hdOperation_SET(INT)"));
				// check if value changes:
				if ((*this.*fc_CheckChanged)(pMemory, pValue, bBitIndex) ) {
					// set value
					(*this.*fc_setValue)(pMemory, pValue, bBitIndex);
					// check if need to transmit new value
					if (bOperation == hdOperation_SET) {
						bOperation = hdOperation_TRANSMIT;
					} else {
						// callback 'ValueChanged'
					}
				}
			} break;
			case hdOperation_TRANSMIT:{
				Serial.println(F("hdOperation_TRANSMIT"));
				Serial.print(F(" MemoryValue:"));
				Serial.println((*(uint16_t *)pMemory));
				//printValue_Byte(streamCommunication, pMemory);
			} break;
		} // end switch bOperation
	} while (bOperationOld != bOperation);
	
	return 1;
};

i don't know if the described would be a 'nice' solution -
is there a other solution / way / concept for this problem out there?

i have appended my main sketch -
its a library so put it in your sketchbook/libraries/ folder. it contains a example.
this is the sketch for testing and developing all functionality..
short description what is does:
read the serial port.
if it receives a complete line (checks for line endings and prevents from internal buffer overflows...)
parse this line.
--> use the handleData function in 'hdOperation_RECEIVE' mode.

this handleData function is the main construct to interface the internal representation of the system data.
and my idea / goal ist to only have one interface for internal get / set and external transmit / receive operations

i hope someone has a tip / idea about what ways to go with this... :slight_smile:

sunny greetings stefan

slight_2ChComLink__20140411_1127.zip (15.1 KB)

test_functionpointer.ino (9.83 KB)