#Define en meerdere klassen gebruiken

Ik gebruik de FastLED-bibliotheek in mijn programma en het basisgebruik is dat de volgende regels boven aan de hoofdschets staan:

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

You can see the documentation at https://github.com/FastLED/FastLED/wiki/Basic-usage

Ik gebruik de FastLED-bibliotheek echter in verschillende objecten in mijn programma en ik zou graag willen kunnen verwijzen naar NUM_LEDS in verschillende header-bestanden voor elk object, zodat het aantal LEDS kan worden geregeld door de waarde in de hoofdschets te wijzigen .

Ik ben ook van plan om mijn eigen objecten in bibliotheken te maken zodat anderen ze kunnen gebruiken, zodat ze vervolgens de instellingen in hun hoofdschets zullen definiëren, die mijn bibliotheken dan zullen gebruiken.

0
Zeker ... Maak een headerbestand met deze drie regels (noem het bijvoorbeeld FastLedInclude.h ) en typ vervolgens in elk bestand de FastLed-bibliotheek, schrijf # include "FastLedInclude. h " in plaats van # include
toegevoegd de auteur Tom Collins, de bron
U moet NUM_LEDS hebben gedefinieerd in elk bestand dat u compileert; dat is waarom je het nodig hebt in een headerbestand dat door elk cpp- of ino-bestand moet worden opgenomen. Als u nu een bibliotheek wilt maken, moet dat bestand zich in 1) de bibliotheekmap bevinden, of 2) de schetsmap. De tweede benadering is, IMHO, zeer slecht, omdat het de gebruiker vereist om het bestand in zijn schetsmap aan te maken en vereist dat de bibliotheek weet waar de schets is, wat tegen de definitie van "bibliotheek" is, dat wil zeggen een stukje code dat kan zelfstandig werken. Mijn persoonlijk advies is om de gebruiker te vragen om het bibliotheekbestand aan te passen of, als je dat niet wilt
toegevoegd de auteur Tom Collins, de bron
om hem te dwingen/toe te staan ​​om uw bestanden aan te passen, bewerkt u de code met behulp van dynamische toewijzing in plaats van de statische toewijzing van de compilatie. Ik bedoel, in plaats van DATA_PIN te definiëren, kun je een uint8_t-variabele in je klas opslaan die de datapin bevat. U kunt hetzelfde doen met NUM_LEDS en vervolgens de matrix dynamisch (met malloc s of nieuw s) in de code toewijzen. Het kan lagere uitvoeringen hebben, maar het zal beter werken
toegevoegd de auteur Tom Collins, de bron
Nou, jouw bibliotheek zal minstens één klasse bevatten, nietwaar? Daarom kunt u de variabele in uw klas opslaan en vervolgens openbaar (slecht) of privé (beter) maken en in de constructor plaatsen. Dus de gebruiker moet uw object dynamisch toewijzen uwklasse * obj = nieuw uw klasse (60); (of, als hij #define NUM_LEDS 60 heeft gedefinieerd, kan hij yourclass * obj = nieuw yourclass (NUM_LEDS); ) of statisch yourclass obj (60); (of yourclass obj (NUM_LEDS); ). In beide gevallen heeft u de waarde opgeslagen in uw object
toegevoegd de auteur Tom Collins, de bron
Natuurlijk kun je een variabele NIET DEFINIËREN in een header, anders kun je het meerdere keren definiëren. Je kunt het zeker VERKLAREN, en je zou het extern moeten declareren, en het vervolgens in slechts één cpp- of ino-bestand moeten definiëren. De gebruikelijke manier is om 1) extern struct CRGB leds []; in het bestand FastLedInclude.h te schrijven. 2) kies een ino- of cpp-bestand (waarschijnlijk is het belangrijkste ino-bestand niet het meest aangegeven, maar zou moeten werken) en schrijf struct CRGB leds [NUM_LEDS]; . Als dit niet werkt, plaats dan je code en ik zal proberen het te bekijken
toegevoegd de auteur Tom Collins, de bron
Ik voegde het antwoord met nog enkele voorbeelden toe ..
toegevoegd de auteur Tom Collins, de bron
Dit zal niet werken omdat iemand die mijn bibliotheek in zijn eigen fastLED-schets gebruikt, dan niet in staat is om zijn eigen projectgrootte te bepalen uit de hoofdschets. Ik zal mijn vraag wijzigen om ervoor te zorgen dat dit wordt begrepen.
toegevoegd de auteur Slacker, de bron
Dat is erg handig. Ik vraag me af of ik de gebruiker kan vragen om const-byte numberOfLeds = NUM_LEDS toe te voegen aan zijn sketch en vervolgens numberOfLeds te gebruiken in mijn bibliotheek in plaats van NUM_LEDS ?
toegevoegd de auteur Slacker, de bron
en voeg dan een aanwijzer toe aan const byte numberOfLeds in mijn bibliotheekkop?
toegevoegd de auteur Slacker, de bron
Dit is erg nuttig, hartelijk dank. Ik heb geprobeerd de # include "FastLedInclude.h" -versie die u voor het eerst heeft voorgesteld, te implementeren en ik realiseerde me dat ik niet alle informatie in de vraag heb gegeven. De FastLED-configuratie vereist ook dat ik CRNL-leds [NUM_LEDS]; aan de pagina's toevoeg waar de code wordt gebruikt. Als ik dat opneem in FastLedInclude.h dan krijg ik een compileerfout meervoudige definitie van 'leds'
toegevoegd de auteur Slacker, de bron
Ik heb geprobeerd met behulp van CRGB-leds [NUM_LEDS]; in de hoofdschets en externe CRGB * leds; in mijn cpp-bestanden te structureren en het compileert, maar het programma werkt niet
toegevoegd de auteur Slacker, de bron
Dit werkt perfect! Heel erg bedankt voor je hulp, voel je vrij om dit als een 'antwoord' bij te dragen
toegevoegd de auteur Slacker, de bron

1 antwoord

Zoals het OP suggereerde, plaats ik een samenvatting van de opmerkingen onder zijn vraag sinds het antwoord werd gevonden.

Om een ​​gemeenschappelijke definitie voor die parameters in verschillende bronbestanden te maken, is de eenvoudigste oplossing om een ​​gedeelde kop te maken. Om dit te doen, maakt u gewoon een nieuw bestand met de naam FastLedInclude.h en, daarbinnen, schrijf

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

Dan moet u in elk bronbestand #omvatten "FastLedInclude.h" om die bibliotheek te kunnen gebruiken.

De FastLED-bibliotheek vereist ook dat de programmeur een struct maakt. Het plaatsen van de definitie van de struct (dat wil zeggen struct CRGB leds [NUM_LEDS]; ) in het header-bestand leidt tot compilatiefouten, omdat de compiler de code schrijft om het eenmaal voor elk objectbestand toe te wijzen.

De juiste manier om dit te delen tussen verschillende objectbestanden is om het extern in de header te declareren en het dan één keer in een van de cpp- of ino-bestanden te definiëren:

// into FastLedInclude.h
extern struct CRGB leds[];

// into any cpp or ino file (but just once)
struct CRGB leds[NUM_LEDS];

Dit kan ook gedaan worden in het belangrijkste ino schetsbestand, maar persoonlijk geef ik er de voorkeur aan om het in een ander te definiëren (het hangt er echter van af hoe je het programma opsplitst).

Als u een bibliotheek wilt maken, ontstaan ​​er een aantal andere problemen. De eenvoudigste oplossing is om de gebruiker te vragen het headerbestand dat zich in de bibliotheekmap bevindt handmatig te wijzigen. Deze oplossing is een beetje ongemakkelijk, maar het is de veiligste oplossing.

Een andere oplossing is om de gebruiker te dwingen een headerbestand in de schetsmap te maken. Vervolgens moet de bibliotheek het pad van de schemapap kennen om deze terug te zetten. Maar .. Dit is een zeer ontmoedigde optie, omdat het vereist dat de bibliotheek de schetslocatie kent, waardoor het consistentieprincipe wordt geschonden aan de basis van een bibliotheekgebaseerde benadering.

De derde oplossing is om de aanpak te wijzigen, van een statische definitie van compileren tot een dynamische definitie. Om dit te doen, hoeft u in plaats van het definiëren van NUM_LEDS en DATA_PIN tijdens het compileren deze als variabelen in de bibliotheekklasse op te slaan.

Bijvoorbeeld in uw bibliotheekklasse-definitie die u hebt

class yourclass
{
    public:
        yourclass(uint8_t data_pin, uint8_t num_leds);
        ~yourclass();
    private:
        uint8_t _data_pin;
        uint8_t _num_leds;
        struct CRGB *leds = NULL;
};

En de implementatie kan zijn

yourclass::yourclass(uint8_t data_pin, uint8_t num_leds)
{
    _data_pin = data_pin;
    _num_leds = num_leds;

   //Dynamic allocation of the array
    leds = (struct CRGB *) malloc(num_leds * sizeof(struct CRGB));
}

yourclass::~yourclass()
{
   //you should free the leds array when done
    free(leds);
}

Dan kan de gebruiker schrijven

yourclass *obj = new yourclass(6, 60);

// or, if he wants to define,
#define NUM_LEDS 60
#define DATA_PIN 6
...
yourclass *obj = new yourclass(DATA_PIN, NUM_LEDS);

of, in het geval van een statisch toegewezen object,

yourclass obj(6, 60);

// or, if he wants to define,
#define NUM_LEDS 60
#define DATA_PIN 6
...
yourclass obj(DATA_PIN, NUM_LEDS);
1
toegevoegd
Super bedankt! Dat is een geweldig antwoord :)
toegevoegd de auteur Slacker, de bron