Struct mit Function Pointer + Array

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Struct mit Function Pointer + Array

Beitrag von chris_1981_ » Do Jan 14, 2016 12:03 am

Hallo zusammen,

eigentlich bin ich kein wirklich guter User hier im Forum, ich stelle meist nur Fragen anstatt auch einmal irgendwas zu Lösung beizutragen.
Vielleicht seit ihr aber doch noch ein wenig gnädig mir diese Frage zu beantworten?

Ich habe folgende Situation: Ich möchte gerne ein LCD Menü generieren, das Menü funktioniert eigentlich schon, aber ich stelle fest je größer das Menü wird, desto mehr Funktionen hat, das wäre eigentlich auch ok, aber ca. 90 % der Funktionen sind gleich, da Sie nur eine Variable vom Inhaltlichen Wert verkleinern oder vergrößern und zusätzlich einen passenden Text über die aktuelle Einstellungssituation ans LCD zu übergeben.
Jetzt wird die Steuerung des Menüs aus einem Array definiert, doch aus dem Array kann ich zwar eine Funktion starten, doch nicht mit "Funktionsargumenten" so wie ich das gerne hätte.

Das original Beispiel in verkürzter Form:
(diese Art des LCD Menüs ist nicht direkt von mir sondern, aus vielen Beispielen zusammengestellt.

Code: Alles auswählen

typedef const struct MenuStructure
{
	const char *text;
	unsigned char m_points;
	unsigned char up;
	unsigned char down;
	unsigned char enter;
	void (*func) ();
}MenuEntry;

const char menu_000[] = "[Setup]";			// 0
const char menu_001[] = " Date & Time";  	        // 1

MenuEntry menu[] =
{
	{menu_000, 8,  0,  0,  0,  0}, 	// 0
	{menu_001, 8,  1,  2,  9,  setValuesByLCDConfiguration},	// 1
};

void setValuesByLCDConfiguration()
{
   printf("CHECK\n");
}

int main (void)
{
    menu[selected].fp();
}
Jetzt habe ich schon versucht, das Array mit den Werten "aufzubrechen" :

Code: Alles auswählen


typedef const struct MenuStructure
{
	const char *text;
	unsigned char m_points;
	unsigned char up;
	unsigned char down;
	unsigned char enter;
	void (*func) ();
    unsigned char *lcdMenu;
    unsigned char *variableDefiniton;
}MenuEntry;

MenuEntry menu[] =
{
	{menu_000, 8,  0,  0,  0,  0}, 	// 0
	{menu_001, 8,  1,  2,  9,  setValuesByLCDConfiguration, 'C', 8, 'X'},	// 1
};

void setValuesByLCDConfiguration( unsigned char *p, int *z,  unsigned char *g)
{
   printf("%c :: %i :: %c \n", p, g););
}

int main (void)
{
    menu[0].fp(menu[0].lcdMenu, menu[0].variableDefiniton);
}
Nur kann ich leider keine "echten" Variablennamen übergeben, welche ich natürlich brauche, wenn ich die einzustellenden Variablen an die Funktion übergeben möchte.
Sollte ich das ganze mit einem weiteren Struct lösen?
Versteht mich Jemand?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Struct mit Function Pointer + Array

Beitrag von Xin » Do Jan 14, 2016 10:30 am

chris_1981_ hat geschrieben:eigentlich bin ich kein wirklich guter User hier im Forum, ich stelle meist nur Fragen anstatt auch einmal irgendwas zu Lösung beizutragen.
Vielleicht seit ihr aber doch noch ein wenig gnädig mir diese Frage zu beantworten?
Wollen mal gucken, ob wir aus Dir noch einen guten User bekommen.
chris_1981_ hat geschrieben:Nur kann ich leider keine "echten" Variablennamen übergeben, welche ich natürlich brauche, wenn ich die einzustellenden Variablen an die Funktion übergeben möchte.
Sollte ich das ganze mit einem weiteren Struct lösen?
Versteht mich Jemand?
Keine Ahnung, ob ich Dich verstehe, aber hast Du nicht alle Informationen in Deiner Struct?

Ansonsten packst Du alle Informationen in Deine Menüstruktur, die Du brauchst und machst eine Struktur mit dem globalen Programmstatus. Beides packst Du in die Funktion und dann soll die Funktion halt den Programmstatus so verändern, wie es die Menüstruktur vorgibt.
Falls ich das Problem richtig verstanden habe?! :D
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Struct mit Function Pointer + Array

Beitrag von chris_1981_ » Do Jan 14, 2016 9:23 pm

Hallo Xin,

du hast mich schon richtig verstanden, dass heißt für mich das so etwas wie:

Code: Alles auswählen

 {menu_001, 8,  1,  2,  9,  setValuesByLCDConfiguration(setYearLCDMenu, yearVariable)},   // 1
 {menu_002, 8,  1,  3,  10,  setValuesByLCDConfiguration(setDayLCDMenu, dayVariable)},   // 2

void setValuesByLCDConfiguration( unsigned char *p,  unsigned char *g)
{
   printf("%c :: %c \n", g););
}
nicht funktionieren würde. Das wäre eigentlich mein 1. Gedanke gewesen, um auch den Code "einfacher" zu halten.
Ich habe nur keine Lösung dafür gefunden, daher hier meine Anfrage

Aber deine Idee hatte ich eigentlich auch schon überlegt,
ich könnte eine Switch and Case Funktion einbauen, damit man das LCD und die betroffenen Variablen ansteuern kann.
Ich wollte nur die Funktion "recht" klein und schlank halten.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Struct mit Function Pointer + Array

Beitrag von Xin » Do Jan 14, 2016 11:07 pm

Ich kann dazu nix sagen, weil ich keine Ahnung habe, wo yearVariable oder dayVariable auf einmal herkommt.

Deine setValuesByLCDConfiguration kompiliert nicht und was soll sie überhaupt tun!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Struct mit Function Pointer + Array

Beitrag von chris_1981_ » Sa Jan 16, 2016 12:01 pm

Hallo Xin,

ok, ich hätte dabei schreiben sollen, woher die Variablen kommen.

Die Variable setYearLCDMenu, wird beim Starten aus dem EEprom gelesen und ist eine Globale Variable.
Die Variable yearVariable wird beim Starten aus dem Flashspeicher geladen und ist auch eine Globale Variable.

In dem letzten Codeschnipsel, war eigentlich nur meine Frage : wie ich es schaffe die Funktion, welche ich aufgezeigt habe:
setValuesByLCDConfiguration aus einem Array Konstrukt mit "verschiedenen" Argumenten zu starten.

Eine vorherige Lösung war es einfach den aktuellen "selected" Wert zu übergeben und eine Switch Case Routine in die Funktion einzubauen.
Nachteil hierbei, die Funktion setValuesByLCDConfiguration wird schon recht groß, bei 23 Einstellungsmöglichkeiten.
Sollte es aber möglich sein, direkt aus dem Array Konstrukt:

Code: Alles auswählen

{menu_001, 8,  1,  2,  9,  setValuesByLCDConfiguration(setYearLCDMenu, yearVariable)},   // 1
{menu_002, 8,  1,  3,  10,  setValuesByLCDConfiguration(setDayLCDMenu, dayVariable)},   // 2
eine Funktion mit Variablen aufzurufen, kann ich mir die Switch Case Routine in der Funktion setValuesByLCDConfiguration sparen.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: Struct mit Function Pointer + Array

Beitrag von chris_1981_ » So Feb 07, 2016 3:11 pm

Hallo zusammen,

ich hatte ja angefragt, gibt es eine Möglichkeit einem Struct Funktionspointer eine Variable zu übergeben, wo sich der Inhalt der übergebenen Variable in einem Array befindet.
Bitte stört euch nicht an dem Attribute __flash, das ganze läuft auf einem Atmega8.
ich habe nun eine Möglichkeit überlegt / gefunden, mit der ich umgehen kann:

Code: Alles auswählen


#include <avr/io.h>
#include "CMLcdMenu.h"
#include "CMDisplayHD44780.h"
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <stdlib.h>

// Menustructure
typedef const struct MenuStructure
{
	const __flash char *text;
	unsigned char num_menupoints;
	unsigned char up;
	unsigned char down;
	unsigned char enter;
	void (*fp) ();
	uint8_t *value;
	uint8_t *min;
	uint8_t *max;
	unsigned char *useEEprom;
	unsigned char *eepromAddress;
}MenuEntry;

/**
	@brief	Define and Initialize the external
			variables
	@param 	none
	@return	none
*/
extern uint8_t day;
extern uint8_t month;
extern uint8_t weekday;
extern uint8_t year;
extern uint8_t hour;
extern uint8_t sec;
extern uint8_t min;

/**
	@brief	Define and Initialize the menu
			definitions
	@param 	none
	@return	none
*/
const __flash char menu_100[]  = "[Date & Time]"; 	// 8
const __flash char menu_101[]  = " Set-> Hour";		// 9
const __flash char menu_102[]  = " Set-> Minute";  	// 10
const __flash char menu_103[]  = " Set-> Day";		// 11
const __flash char menu_104[]  = " Set-> Month";  	// 12 
const __flash char menu_105[]  = " Set-> Year";  	// 13
const __flash char menu_106[]  = " Exit"; 			// 14

/**
	@brief	Define and Initialize the menu
			entry
	@param 	none
	@return	none
*/
const __flash MenuEntry menu[] =
{
{menu_100,  7,  0,  0,  0,  0},													// 8
	{menu_101,  7,  9, 10,  9,  setValuesByLCDConfiguration, &hour,   0, 23, 0, 0},	// 9
	{menu_102,  7,  9, 11, 10,  setValuesByLCDConfiguration, &min,    0, 59, 0, 0},	// 10
	{menu_103,  7, 10, 12, 11,  setValuesByLCDConfiguration, &day,    1, 31, 0, 0},	// 11
	{menu_104,  7, 11, 13, 12,  setValuesByLCDConfiguration, &month,  1, 12, 0, 0},	// 12
	{menu_105,  7, 12, 14, 13,  setValuesByLCDConfiguration, &year,  10, 50, 0, 0},	// 13
	{menu_106,  7, 13, 14,  1,  },		
};

/**
	@brief	Define and Initialize setValuesByLCDConfiguration
			routine
	@param 	none
	@return	none
*/
void setValuesByLCDConfiguration(uint8_t *setValue, uint8_t *minValue, uint8_t *maxValue, uint8_t *useEeprom, uint8_t *eepromAddress)
{
	uint8_t tmp = 0;				// Temporary variable
	
	// setup the variable
	// which want to define
	tmp = *setValue;
        ...............................
}
Kann man mit den geringen Infos etwas anfangen?
Was ich aber nun definiert habe ist, ich übergebe aus dem Array die "Speicherstelle" der externen Variable an den Funktionspointer, somit kann ich den Inhalt der Variable ändern. Gleichzeitig ist es so, dass die Funktion "setValuesByLCDConfiguration" nun die "wichtigen" Eigenschaften für diesen Menüe -Eintrag gleichzeitig übergeben bekommt. Mit dieser Möglichkeit kann ich dieses Menu Grundsätzlich nutzen, ohne ständig zig Zeilen vom Code neu zuschreiben.
Nach Änderung der Variablen wird in der Funktion noch geprüft, ob diese Variable eine Speicherung / Aktualisierung im EEprom benötigt und dieses wird das auch direkt durchgeführt.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Struct mit Function Pointer + Array

Beitrag von Xin » Di Feb 09, 2016 1:22 pm

Nein.



Das war jetzt der dritte Versuch, den Text zu lesen... Sonntag abend, gestern und halt jetzt. Ich weiß es wirklich nicht, ob ich derzeit einfach nur zu blöd bin, das Problem zu verstehen oder es daran liegt, dass ich nicht vorhabe den Quelltext komplett zu lesen und den Text zu simplifizieren. Ich schreibe ja manchmal Stuss, aber die Sätze sind so geschrieben, dass sie nur verwirren und der Block Code hilft auch nicht, da man nicht weiß, wo an der man hingucken muss.
Und schlussendlich: Die einzige Frage ist, ob man mit den Informationen etwas anfangen kann.
Antwort siehe oben. ^^
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten