Funktionen konvertieren

OP #7311823
Lesenswert?

Hi,

angenommen man hat eine Funktion vom Type:

static int eeprom_get(char adr, char* ptr);

Ich möchte aber nicht jedes mal meinen Pointer und die EEPROM-Adresse mitgeben. Wenn man einer Funktion feste Parameter übergibt, sodass kann man dann die Funktionen so "umcasten"?

int (*eeprom_get_parameter)(void) = eeprom_get(parameter_adr, &parameter);

  • "Parameter_adr" ist die konstante EEPROM-Adresse wo die Daten hinterlegt sind.
  • "&Parameter" ist konstante Pointer zur Addresse im RAM, wo der Wert von "parameter" hinterlegt wird.

Gruß

P.S.: Ich rede hier von der Programmiersprache C und dem Compiler XC8 und IDE MPLAB. Letztere beide sind von Microchip.

Persönliche Seite #7311832
Lesenswert?

Das nennt sich Currying und wird so nur von funktionalen Sprachen unterstützt (z.B. Scala). In C++ gibt es dafür std::bind oder etwas schöner Lambdas (mit Cloure).

In C geht das nicht wirklich. Sofern die Parameter-Ausdrücke immer vorhanden sind, kannst du einfach ein Makro definieren. Oder beide Werte in ein struct packen, welches du an eine Hilfs-Funktion übergibst, die dann die beiden Werte an eeprom_get übergibt; das ist dann ein semi-OOP-Ansatz.

Moderator Persönliche Seite #7311837
Lesenswert?

Niklas G. schrieb:

Sofern die Parameter-Ausdrücke immer vorhanden sind, kannst du einfach ein Makro definieren.

So klingt mir seine Beschreibung, und in der Tat könnte man das mit einem Makro machen.

1
char eeprom_data;
2

3
#define EEPROM_ADDRESS 42
4
#define EEPROM_GET() eeprom_get(EEPROM_ADDRESS, &eeprom_data)
5

6
// ...
7

8
  EEPROM_GET();
9
  // ...
10
  EEPROM_GET();

Schön ist natürlich was anderes. ;-)

OP #7311846
Lesenswert?

Ja das ist genau was ich meinte.

Schön ist es wirklich nicht. Auch ein Workaround sind Wrapper.

1
int eeprom_get_parameter(void){
2
   return eeprom_get(PARAMTER_ADR, &parameter);
3
}

Ist aber genau so wenig schön wie Macros.

Schade das es nicht geht :/ Hätte einiges schöner gemacht.

Danke für die Antworten :)

#7312539
Lesenswert?

Aabeku K. schrieb:

Ja das ist genau was ich meinte.

Schön ist es wirklich nicht. Auch ein Workaround sind Wrapper.

1
> int eeprom_get_parameter(void){
2
>    return eeprom_get(PARAMTER_ADR, &parameter);
3
> }
4
> 
5
>

Das ist doch genau das, was Du wolltest! Kannst Du inline deklarieren und ab in die entsprechende Header-Datei.

Was findest Du daran unschön?

Vielleicht möchtest Du es aber eher so benutzen können?

1
void f() {
2
    int v = eeprom_get(Parameter_A);
3
}
#7312569
Lesenswert?

Niklas G. schrieb:

Das nennt sich Currying und wird so nur von funktionalen Sprachen unterstützt (z.B. Scala). In C++ gibt es dafür std::bind oder etwas schöner Lambdas (mit Cloure).

Aus seiner Beschreibung sehe ich nicht, dass er eine N-stellige Funktion auf N Aufrufe einstelliger Funktionen abbilden will.

In C geht das nicht wirklich.

In GCC kann man lokale Funktionen definieren als Erweiterung. Vielleicht geht das bei dem XC8 auch?Damit könnte man dann tatsächlich "schönfinkeln" aka currying.

#7312610
Lesenswert?

Ich mag das nicht, überall durcheinander im Code vom EEPROM lesen oder schreiben. Ich lege mir daher ein Struct an, das alle Variablen enthält, die im EEPROM gesichert werden sollen. Und dann wird nur einmalig die Struct aus dem EEPROM gelesen, bzw. dahin gesichert. Damit muß man keine Extrawurst für alle EEPROM-Variablen braten. Es sind ganz normal zugreifbare Variablen, die nach dem Reset aus dem EEPROM initialisiert werden.

Und das Sichern der Struct in den EEPROM erfolgt als Hintergrundtask (per Polling in der Mainloop), damit für die Schreibdauer die Applikation nicht angehalten werden muß.

Gast #7313123
Lesenswert?

Aabeku K. schrieb:

angenommen man hat eine Funktion vom Type:

static int eeprom_get(char adr, char* ptr);

Ich möchte aber nicht...

Wenn du so eine Funktion hast und sie dir nicht gefällt, dann schreib dir einfach eine bessere Funktion.

Gerade EEPROMs werden recht häufig seriell betrieben, weswegen da ein char* Zeiger nicht wirklich hinpaßt.

Selbst bei auf dem Chip eingebautem EEPROM ist es oft so, daß es feste HW-Register gibt, wo man Adresse und Sollinhalt hineinschreibt und dann ein Schreiben auslöst oder nur Adresse und Lesen auslösen und dann den Istinhalt aus einem HW-Register holen.

Irgendwelche Präprozessor-Akrobatik halte ich für übel, denn sie macht das Ganze nur undurchsichtiger und die vorhandene Funktion nicht besser.

W.S.

Gast #7323171
Lesenswert?

Schön ist es wirklich nicht. Auch ein Workaround sind Wrapper.

Tja, unter den 10.000 C++23 Features findest du mindestens ein dutzend Features, mit denen du dein "umcasten" bauen kannst.

Musst dich halt entscheiden. Entweder eine Sprache, in der du dich auf struct[] und Wrapper beschränken musst. Oder eine Sprache, bei der du erst mal einen Kubikmeter Lehrbücher und Spezifikationen durcharbeiten musst.

#7323398
Lesenswert?

Noch ein Kommentar schrieb:

Schön ist es wirklich nicht. Auch ein Workaround sind Wrapper.

Tja, unter den 10.000 C++23 Features findest du mindestens ein dutzend Features, mit denen du dein "umcasten" bauen kannst.

Musst dich halt entscheiden. Entweder eine Sprache, in der du dich auf struct[] und Wrapper beschränken musst. Oder eine Sprache, bei der du erst mal einen Kubikmeter Lehrbücher und Spezifikationen durcharbeiten musst.

Und Du hast den Beitrag nicht gelesen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren