Выкарыстанне #define і некалькі класаў

Я выкарыстоўваю бібліятэку FastLED ў маёй праграме і асноўнае выкарыстанне з'яўляецца тое, што наступныя радкі ідуць у верхняй частцы асноўнага эскіза:

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

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

Тым не менш, я выкарыстоўваю бібліятэку FastLED ў некалькіх розных аб'ектаў, у маёй праграме, і я хацеў бы, каб мець магчымасць спасылацца на NUM_LEDS ў розных файлах для кожнага аб'екта, так што колькасць LEDS можна кантраляваць толькі шляхам змены значэння ў асноўны эскіз ,

Я таксама мае намер, што мае ўласныя аб'екты могуць быць зробленыя ў бібліятэкі для іншых, каб выкарыстаць, так што яны будуць затым вызначыць параметры ў іх асноўным эскізе, што мае бібліятэкі будуць выкарыстоўваць.

0
Вядома .. Стварыць файл загалоўка, які змяшчае гэтыя тры лініі (назавем яго, напрыклад, FastLedInclude.h ), а затым, у кожным файле вам патрэбна бібліятэка FastLed, напісаць #include «FastLedInclude. ч " замест #include
дададзена аўтар Tom Collins, крыніца
Вам трэба будзе мець NUM_LEDS, вызначаныя ў кожным файле кампіляцыі; Вось чаму вам гэта трэба ў загалоўкавыя файл павінны быць уключана кожным CPP ці іншым файлам. Цяпер, калі вы хочаце, каб зрабіць бібліятэку, гэты файл павінен быць альбо ў 1) у тэчцы бібліятэкі, або 2) эскіз тэчкі. Другі падыход, імхо, вельмі дрэнна, так як яна патрабуе ад карыстальніка, каб стварыць файл у эцюднік і патрабуе бібліятэкі, каб ведаць, дзе эскіз, што супярэчыць вызначэнні «бібліятэка», то ёсць кавалак кода, які можа працаваць сам па сабе. Мой асабісты савет, каб папрасіць карыстальніка выправіць файл бібліятэкі або, калі вы не хочаце
дададзена аўтар Tom Collins, крыніца
каб прымусіць/дазволіць яму змяняць файлы, рэдагаваць код, выкарыстоўваючы дынамічнае выдзяленне замест часу кампіляцыі статычнага размеркавання. Я маю на ўвазе, замест вызначэння DATA_PIN вы можаце захоўваць зменную uint8_t у сваім класе, які змяшчае штыфт дадзеных. Вы можаце зрабіць тое ж самае з NUM_LEDS , а затым вылучыць матрыцу дынамічна (з Таноса s або новы S) у кодзе. Ён можа мець больш нізкія выступу, але ён будзе працаваць лепш
дададзена аўтар Tom Collins, крыніца
Ну, ваша бібліятэка будзе трымаць па крайняй меры адзін клас, ці не так? Такім чынам, вы можаце захоўваць зменную ў класе, а затым альбо зрабіць яго публічным (дрэнна) або прыватныя (лепш) і ўсталяваць яго ў канструктару. Такім чынам, карыстальнік павінен будзе вылучыць свой аб'ект дынамічна YourClass * OBJ = новы YourClass (60); (ці, калі ён вызначаны #define NUM_LEDS 60 , ён можа напісаць <�код > YourClass * OBJ = новы YourClass (NUM_LEDS); ) або статычна YourClass OBJ (60); (ці YourClass OBJ (NUM_LEDS); ). У любым выпадку вы будзеце мець значэнне, якое захоўваецца ў вашым аб'екце
дададзена аўтар Tom Collins, крыніца
Вядома, вы не можаце вызначыць зменную ў загалоўку, у адваротным выпадку вы можаце здарыцца, каб вызначыць яго больш чым адзін раз. Вы, безумоўна, можаце DECLARE, і вы павінны аб'явіць яго ехЬегп, а затым вызначыць яго толькі ў адным файле CPP або іна. Звычайны спосаб 1) напісаць ехЬегп структура CRGB святлодыёды []; у файле FastLedInclude.h. 2) абраць Ян або CPP файл (верагодна, асноўны файл іна не самы паказана, але павінен працаваць) і пісаць структуру CRGB святлодыёды [NUM_LEDS] . Калі гэта не працуе, размясціць свой код, і я паспрабую, каб зірнуць на яго
дададзена аўтар Tom Collins, крыніца
Я дадаў адказ з яшчэ некалькі прыкладаў ..
дададзена аўтар Tom Collins, крыніца
Гэта не будзе працаваць, як нехта з дапамогай маёй бібліятэкі ў іх ўласным fastLED эскіз не будзе мець магчымасць вызначыць свой уласны памер праекта ад асноўнага эскіза. Я змяніць маё пытанне, каб пераканацца, што зразумеў.
дададзена аўтар Slacker, крыніца
Гэта вельмі карысна. Цікава, калі б я мог я спытаць карыстальніка, каб дадаць Вуснаў байт numberOfLeds = NUM_LEDS іх эскіз, а затым выкарыстоўваць numberOfLeds у маёй бібліятэцы, а не NUM_LEDS ?
дададзена аўтар Slacker, крыніца
а затым дадаць паказальнік Вуснаў байт numberOfLeds ў маім загалоўку бібліятэкі?
дададзена аўтар Slacker, крыніца
Гэта вельмі карысна, вялікі дзякуй. Я спрабаваў рэалізаваць #include «FastLedInclude.h» версія, што спачатку прапанаваную, і я зразумеў, што я не даваў усю інфармацыю ў гэтым пытанні. Ўстаноўка FastLED таксама мае патрэбу ўва мне, каб дадаць структура CRGB святлодыёды [NUM_LEDS]; на старонках, дзе выкарыстоўваецца код. Калі б я ўключыў, што ў FastLedInclude.h тады я атрымліваю памылку кампіляцыі множным вызначэнне «святлодыёдах»
дададзена аўтар Slacker, крыніца
Я паспрабаваў з дапамогай структура CRGB святлодыёды [NUM_LEDS]; ў галоўным эскізе і экстэрнам CRGB * святлодыёды; у маіх CPP файлы і кампілюе, але праграма не працуе
дададзена аўтар Slacker, крыніца
Гэта выдатна працуе! Вялікае вам дзякуй за вашу дапамогу, не саромейцеся ўносіць гэта ў якасці «адказу»
дададзена аўтар Slacker, крыніца

1 адказы

Як было прапанавана ОП, я адпраўляю падвядзенне заўваг па яго пытанню, бо адказ быў знойдзены.

Для таго, каб вызначыць агульныя для гэтых параметраў у розных зыходных файлах, самае простае рашэнне, каб зрабіць агульны загаловак. Каб зрабіць гэта, проста стварыць новы файл з імем FastLedInclude.h і, унутры гэтага, напісаць

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

Затым у кожным зыходным файле вы будзеце толькі #include «FastLedInclude.h» , каб мець магчымасць выкарыстоўваць гэтую бібліятэку.

Бібліятэка FastLED таксама патрабуе ад праграміста для стварэння структуры. Цяпер, калі размяшчалі вызначэнне структуры (г.зн. структура CRGB святлодыёды [NUM_LEDS]; ) у файл загалоўка прыводзіць да памылак кампіляцыі, так як кампілятар запісвае код вылучыць яго адзін раз для кожнага файла аб'екта.

Правільны спосаб падзяліцца гэтым сярод розных аб'ектных файлаў, каб аб'явіць яго ехЬегп у загалоўку, а затым вызначыць яго толькі адзін раз у адным з CPP або замеж файлаў:

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

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

Гэта таксама можа быць зроблена ў галоўным файле іна эскіза, але асабіста я аддаю перавагу, каб вызначыць яго ў іншы (гэта залежыць, аднак, ад таго, як вы вырашылі падзяліць праграму).

Калі вы хочаце стварыць бібліятэку, узнікаюць іншыя праблемы. Самае простае рашэнне, каб папрасіць карыстальніка ўручную мадыфікаваць файл загалоўка, які будзе знаходзіцца ў тэчцы бібліятэкі. Гэта рашэнне крыху няёмка, але гэта самы бяспечны.

Іншым рашэннем з'яўляецца прымусіць карыстальніка стварыць загалоўкавыя файл у тэчку эскіза. Тады бібліятэка павінна ведаць эскіз шлях да тэчцы для рэзервовага ўключыць яго. Але .. Гэта вельмі збянтэжаны варыянт, так як гэта запатрабуе бібліятэку ведаць эскіз месцазнаходжанне, парушаючы тым самым прынцып несупярэчлівасці на аснове падыходу бібліятэкі на аснове.

Трэцяе рашэнне заключаецца ў змене падыходу, з статычнага вызначэння часу кампіляцыі да дынамічнай. Для таго, каб зрабіць гэта, замест вызначэння NUM_LEDS і DATA_PIN падчас кампіляцыі вы захаваеце іх у якасці зменных у класе бібліятэкі.

Напрыклад, у вызначэнні вашага класа бібліятэкі ў вас ёсць

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;
};

І рэалізацыя можа быць

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);
}

Затым карыстальнік можа напісаць

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);

ці, у выпадку статычны вылучаны аб'ект,

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
дададзена
Супер, дзякуй! Гэта выдатны адказ :)
дададзена аўтар Slacker, крыніца