Re: C++ stream in variable referenzieren
Konrad Rosenbaum <[email protected]> Wed, 3 Apr 2024 15:21:47 +0200
| Newsgroups | gmane.user-groups.linux.dresden |
|---|---|
| Message-ID | <[email protected]> |
Hi,
On 02/04/2024 21:54, Sebastian Reinhardt wrote:
> Ich steh mal wieder etwas auf dem Schlauch und ich hoffe, dass mir
> einer von euch den "Schubs" in die richtige Richtung geben kann.
Willkommen auf dem Schlauch. Beim Abstieg bitte Vorsicht, es sind Knoten
an unerwarteten Stellen...
> Erstmal die Voraussetzungen:
>
> Ich habe an einem PC/PI mehrere I2C-GPIO- Porterweiterungen (MCP23017
> und MCP23008) hängen. Die haben 16 bzw. 8 GPIO's und hängen mit
> verschiedenen Adressen am I2C.
>
> Nun möchte ich diese Bausteine mit C++ über I2C mit entsprechenden
> Bibliotheken (MCP23017 und MCP23008) direkt ansteuern. Die jeweilige
> Bezeichnung, Busadresse usw. lese ich aus einer text/csv-DAtei ein und
> rufe diese Daten aus der Vectorvariable (mcp_elements mit eigener
> struct) ab. Das funktioniert soweit auch, z.B.:
>
> -------code-------
>
> MCP23017 mcpout1.(atoi(mcp_elements[i_e].busnr.c_str()),
> atoi(mcp_elements[i_e].busaddr.c_str()));
>
> mcpout1.openI2C();
>
> for ( int i17 = 0; i17 < 16; i17++) {
>
> mcpout1.pinMode(i17, OUTPUT);
> mcpout1.pinMode(i17, LOW);
>
> }
>
> -------/code-------
>
> Nun muss ich eben für jeden Baustein das Device mit dem
> Handle/ostream verbinden und benötige eben z.B. "mcpout1", "mcpout2",
> "mcpout3" usw. Da ich aber nicht sicher weiss, ob immer die gleiche
> Anzahl von I2C- Bausteinen an den Bus angeschlossen sind, ist diese
> "Hardcodierung" ungünstig. Um nicht jedes mal das Programm anpassen
> und neu kompilieren zu müssen, möchte ich die Art (MCP23008/MCP23017),
> Busadresse, Art der Ports (In-/Outputs) Nummerierung der Ports usw.
> aus der txt/csv-Datei lesen und das etwas dynamisch behandeln. Das
> Lesen der Infos klappt schon, aber dann hänge ich....
Ohne zu wissen wie das alles unter der Haube funktioniert ist der Rest
dieser Mail eher spekulativ.
> Nun die Frage: Kann ich eine Variable (event. einen Vector) erstellen
> in den ich dann in einer Zeile "Nr", "Streamref", "Portnummerstart",
> "Portnummerende" speichern kann und dann eben nur diese eine Variable
> in die anderen Unterprogramme übergeben kann? D.h., kann ich in dieser
> Variable, und wenn ja wie, die Streamreferenz speichern und übergeben
> kann. In den Unterprogrammen möchte ich die Variable nach dem Schema
> "liegt die anzusteuernde Portnummer zwischen "Start" und "Ende", dann
> ist der Stream/ Referenz zu verwenden benutzen.
Natürlich kannst Du komplexe Strukturen/Klassen mit Referenzen bauen und
übergeben. Wir reden hier über C++, da geht sowas.
Profi-Tip: übergib diese Variable als "const MyClass&" an
Unterfunktionen - das geht schneller/effizienter (nur ein Pointer auf
dem Stack statt einer Kopie der Struktur). Im Vektor bitte als volle
Kopie, sonst gibt es schnell Probleme.
> Wie müsste die Variable aussehen? Vector mit welcher struct?
Vector ist gut. Struct ist reichlich veraltet - benutz' doch einfach
C++! ;-)
Bei sowas baue ich mir gerne kleine Helferklassen. Zum Beispiel:
class McpOutRef {
MCP23017 &ref;
int start=0,end=0;
public:
McpOutRef(MCP23017&aref,int astart,int
aend):ref(aref),start(astart),end(aend){}
McpOutRef(const McpOutRef&)=default;
McpOutRef(McpOutRef&&)=default;
McpOutRef& operator=(const McpOutRef&)=default;
McpOutRef& operator=(McpOutRef&&)=default;
bool containsPort(int port)const{return astart<=port && aend>=port;}
MCP23017& mcp()const{return ref;}
};
Über containsPort könntest Du abfragen ob der gesuchte Port zu dieser
Instanz gehört und über mcp() bekommst Du die Referenz.
Wenn man intern Pointer und extern Referenz benutzt, dann kann man noch
etwas mehr "Magie" machen (z.B. saubere "Null-Refs"), aber das führt
hier zu weit.
Du kannst Dir auch den Vektor erweitern:
class McpRefVector: public std::vector<McpOutRef> {
bool hasPort(int port){
for ( const auto&elem : *this) if(elem.containsPort(port))
return true;
return false;
}
McpOutRef& byPort(int port) { .... }
}
Es fehlt noch etwas "Boilerplate" für Constructor, etc. ...
Falls Dein Compiler sich über && oder =default beschwert: -std=c++17 -
wir sind ja nicht mehr im finsteren Mittelalter! ;-)
> Wäre toll, wenn mich jemand erleuchten könnte.....oder wenigstens den
> Weg weisen könnte.
Hell genug?
Konrad
OpenPGP_0xBE96A6EE776FE5D0.asc
(application/pgp-keys, 2.6 KB)
-----BEGIN PGP PUBLIC KEY BLOCK----- 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 GITvFOoOgCafGm48BZJcCkN1rLBx =eE4a -----END PGP PUBLIC KEY BLOCK-----
OpenPGP_signature.asc
(application/pgp-signature, 495 B)
-----BEGIN PGP SIGNATURE----- wsB5BAABCAAjFiEEjkC056IhcKJYJr8GxU4Frrk6fnUFAmYNV+sFAwAAAAAACgkQxU4Frrk6fnW9 1QgAxkiWe9GkVrzyO5DxFb17nPea9E6SS9UGffyHBWxOmmHYMQM5XqtggoZzJpycC1V7B8g41qwW xsByt2vXwptwe2e6yNG8p0l6xva8HY5S0+CsHzsmtfK9VZ8YJoyBvmg7BASodvp2WX9v2naHM27M DA8GR4rgJiDGlki8eDCc9RitzeQ3GNRRB1D1eKLT6GfROqEG/RJf4FUTjY0iJEwfF/L10/5/uslv +1PN5P6CIexw9pvfteZs3z8PNtaOOtipJCn88j8Grb+swoVVar0GReAtX7FNWEhT/7CTriZYYLOl WBU3Gyj5Z4Ec1F2X2upNSAtwTi4j6zEZFC8QjCv9VA== =LQ/s -----END PGP SIGNATURE-----