Go Down

Topic: #define außerhalb einer Klasse  (Read 383 times) previous topic - next topic

Martin2toll

Guten Abend .

Ich habe eine Klasse geschrieben die wie folgt aussieht :

Klasse.h :


class klasse{

public:

   void run(){

      void FUNCTION_NAME();

   }

};


Nun würde ich gerne in meiner .ino durch #define den Namen der aufgerufenen Funktion ( FUNCTION_NAME )festlegen.

Eventuell ca so :


#include <Arduino.h>
#include <Klasse.h>

klasse k;

#define FUNCTION_NAME meineFunction


void setup(){

   Serial.begin(9600);


}

void loop(){

   k.run();

}

//Die Funktion die ich zuweisen möchte

void meineFunction(){
   Serial.println("Bin in meiner Funktion");
}



Da es so wie ich es oben beschrieben habe nicht funktioniert ist nun meine Frage, ob das irgendwie möglich ist ?
Danke für Hilfe schon mal voraus !

MfG


michael_x

Bei richtiger Reihenfolge und Verwendung würde sowas wohl gehen,  aber ich sehe den Sinn nicht.

Martin2toll

#2
Apr 19, 2020, 01:01 am Last Edit: Apr 19, 2020, 01:09 am by Martin2toll
Ich möchte eine art Serielle Konsole erstellen. Dabei hab ich ein Kommando so definiert dass immer ein Hash Symbol kommen muss und anschließend ein Index. Bsp : #10,inhalt;

Die Klasse überprüft den Syntax ( den Hash und das Semikolon ) und liest den Hash Index.
Anschließend führt die Klasse eine zum Index zugewiesene Funktion aus, bei der ich den "inhalt" als Parameter übergebe.

Diese Zuweisung der Funktion möchte ich allerdings außerhalb der Klasse machen um die Klasse flexibler verwenden zu können.

Edit :

Ich hab gerade festgestellt dass das eigentliche Problem das ist, dass wenn ich in der Klassen einen define Namen verwende z.b. Serial.println(VALUE); und diese VALUE mit #define VALUE 10 in meiner .ino definiere meldet der Kompiler natürlich dass VALUE in der Klasse nicht definiert ist ...

Kann ich #define so aufrufen dass dieser auch in der Klasse wirksam ist ?

Danke nochmal :p

Serenifly

#3
Apr 19, 2020, 01:05 am Last Edit: Apr 19, 2020, 01:08 am by Serenifly
Für sowas gibt es Funktionszeiger

Einen Funktionsnamen aber als String auslesen und dynamisch direkt irgendeiner Funktion zuordnen geht aber so oder so nicht. Sobald das Programm compiliert ist sind die Namen nicht mehr existent.

DrDiettrich

Ein #define wirkt in einer Datei sofort, der Compiler ersetzt dort alle nachfolgenden Auftreten des Namens durch die definierte Zeichenfolge. In anderen Dateien ist der Name unbekannt.

Es wäre also sinnvoller, die Klasse ganz normal zu definieren, mit irgendwelchen Funktionsnamen, und im Hauptprogramm einen Ersatz für diese Funktionsnamen zu konstruieren.

Oder Du definierst eine einzige Funktion, innerhalb oder außerhalb der Klasse, die den übergebenen Namen in einen Funktionsnamen der Klasse umrechnet und diese Funktion mit dem ebenfalls übergebenen Wert aufruft. Oder sie berechnet aus dem Namen einen Index in einer Funktionstabelle, oder der Index wird durch #define direkt zugewiesen...

Du kannst Dir Windows OLE, ActiveX oder Delphi oder Corba Interfaces anschauen, wie Methoden einer Klasse zur Laufzeit über ihren Namen aufgerufen werden können. In Delphi geht das z.B. mit "published" Methoden und RTTI, vielleicht auch in C#, in C++ kenne ich keine vergleichbare Funktion.

combie

#5
Apr 19, 2020, 08:37 am Last Edit: Apr 19, 2020, 08:39 am by combie
Quote
Nun würde ich gerne in meiner .ino durch #define den Namen der aufgerufenen Funktion ( FUNCTION_NAME )festlegen.
Und ich bitte dich möglichst auf den Präprozessor zu verzichten.
In C++ ist der längst nicht mehr so wichtig.


z.B. könntest du hier evtl mit Lambdafunktionen (und Sprungtabellen) arbeiten.


Quote
und RTTI,
Gibts in C++
Aber nicht für AVR, da fehlen die Libraries, und es bläht den Code auf.
Ein schwarzes Schaf, zur rechten Zeit, erspart den Streit, bringt Einigkeit.

noiasca

Quote
ich möchte eine art Serielle Konsole erstellen. Dabei hab ich ein Kommando so definiert dass immer ein Hash Symbol kommen muss und anschließend ein Index. Bsp : #10,inhalt;

Die Klasse überprüft den Syntax ( den Hash und das Semikolon ) und liest den Hash Index.
Anschließend führt die Klasse eine zum Index zugewiesene Funktion aus, bei der ich den "inhalt" als Parameter übergebe.
für diesen Anwendungsfall: warum nicht einfach über ein switch/case von der erhaltenen Nummer auf die Funktion mappen und dann halt den übernommen Inhalt der Funktion übergeben?
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

combie

Quote
warum nicht einfach über ein switch/case von der erhaltenen Nummer auf die Funktion mappen und dann halt den übernommen Inhalt der Funktion übergeben?
Das kann man selber entwickeln, oder Libs, wie z.B. den CmdMessenger nutzen.

Ein schwarzes Schaf, zur rechten Zeit, erspart den Streit, bringt Einigkeit.

noiasca

OT: den cmdMessenger empfiehlst ja öfters, den werde ich mir mal ansehen. Aber so ein faches Tag-Value parsing, geht imho noch gut zu Fuß.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

combie

#9
Apr 19, 2020, 11:13 am Last Edit: Apr 19, 2020, 11:16 am by combie
Quote
Aber so ein faches Tag-Value parsing, geht imho noch gut zu Fuß.
Du...
Dir traue ich das zu.

Ich sehe das so:
Hier brechen sich min. 3 mal Wöchentlich Leute die Ohren beim Parserbau.
Dabei waren die grundlegenden Verfahren schon bekannt, als man die Computer noch mit Lochstreifen gefüttert hat. Bald 100 Jahre, ist es her.

Da kann man jetzt fertige Libs verwenden, oder sich einarbeiten.
Und zum Einarbeiten ist stochern im Nebel, hier mit #define, oder sonstiges Rumprobieren, eine eher langwierige und frustrierende Beschäftigung.

Man kann also ca 80 Jahre Erfahrung von Hunderten Genies im Netz finden.
Die Gedanken sind vorgekaut verfügbar.

Eine einfache Strategie:
Das C++ Buch: Lesen und das gelesene anwenden.
Das Datenblatt: Lesen und das gelesene anwenden.
Der endliche Automat als Parser: Lesen und das gelesene anwenden.


Quote
den cmdMessenger empfiehlst ja öfters,
Ja, das tue ich.
Denn er ist ein recht einfaches Werkzeug um die Kommunikation zwischen Kontrollern zu ermöglichen.
Das ganze Parser und Dispatcher Thema wird von diesem abgehandelt.

Natürlich kann man auch den Ehrgeiz haben sich das alles selber zu erarbeiten.
(so wie ich?)
Und dann doch den CmdMessenger (o.ä.) benutzen.
(so wie ich!)

Wie auch immer, viele Wege führen nach Rom, der  CmdMessenger ist nur einer davon.
Aber ja, probiere ihn mal aus.
Könnten wir ja auch einen Thread draus machen.
Dann stecken wir vielleicht sogar noch welche an.




Ein schwarzes Schaf, zur rechten Zeit, erspart den Streit, bringt Einigkeit.

Go Up