#Define ve çoklu sınıfları kullanma

Programımdaki FastLED kitaplığını kullanıyorum ve temel kullanım şu çizgilerin ana çizimin en üstündedir:

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

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

Ancak, programımda birkaç farklı nesnede FastLED kütüphanesini kullanıyorum ve her nesne için farklı başlık dosyalarındaki NUM_LEDS referansını kullanmak istiyorum. Böylece LED'lerin sayısı ana çizimdeki değeri değiştirerek kontrol edilebilir. .

Ayrıca kendi nesnelerimin başkalarının kullanması için kütüphaneler içinde yapılabileceğini düşünüyorum, böylece ayarları ana kitaplarında tanımlayacaklar, böylece kütüphanelerim kullanacak.

0
Elbette .. Bu üç satırı içeren bir başlık dosyası oluşturun (örneğin, FastLedInclude.h olarak adlandırın) ve sonra her dosyada FastLed kitaplığına ihtiyacınız var, #include "FastLedInclude yazın. #include yerine h
katma yazar Tom Collins, kaynak
Derlediğiniz her dosyada NUM_LEDS tanımlı olması gerekir; Bu yüzden her cpp veya ino dosyasında yer alan bir başlık dosyasında ihtiyacınız var. Şimdi, bir kütüphane yapmak istiyorsanız, bu dosya 1) kütüphane klasöründe veya 2) çizim klasöründe olmalıdır. İkinci yaklaşım, IMHO, çok kötüdür, çünkü kullanıcının dosyayı çizim klasöründe oluşturmasını ve kütüphanenin taslağın nerede olduğunu bilmesini gerektirir, yani "kütüphane" tanımına aykırıdır, yani bir kod parçası kendi başına çalışabilir. Kişisel tavsiyem, kullanıcıdan kütüphane dosyasını değiştirmesini istemek ya da istemiyorsanız,
katma yazar Tom Collins, kaynak
Dosyalarınızı değiştirmeye zorlamak/izin vermek için, derleme zamanı statik ayırma yerine dinamik ayırma kullanarak kodu düzenleyin. Yani, DATA_PIN 'i tanımlamak yerine, veri pinini içeren sınıfınızda bir uint8_t değişkeni saklayabilirsiniz. Aynı şeyi NUM_LEDS ile yapabilir ve ardından matrise dinamik olarak kodu ( malloc veya yeni ile kodları) atayabilirsiniz. Daha düşük performanslara sahip olabilir, ancak daha iyi çalışır
katma yazar Tom Collins, kaynak
Eh, kütüphaneniz en az bir sınıf içerecek, değil mi? Sonuç olarak, değişkeni sınıfınızda saklayabilir, daha sonra bunu herkese açık (kötü) veya özel (daha iyi) hale getirebilir ve kurucuya ayarlayabilirsiniz. Böylece kullanıcı, nesnenizi dinamik olarak yourclass * obj = new yourclass (60); (veya #define NUM_LEDS 60 olarak tanımladıysa) yazabilir. > yourclass * obj = new yourclass (NUM_LEDS); ) veya statik olarak yourclass obj (60); (veya yourclass obj (NUM_LEDS); ). Her iki durumda da nesnenizde kayıtlı değere sahip olacaksınız.
katma yazar Tom Collins, kaynak
Tabii ki bir başlıktaki bir değişkeni tanımlayamazsınız, aksi takdirde bunu bir defadan fazla tanımlayabilirsiniz. Kesinlikle DECLARE yapabilirsiniz ve extern ilan etmeli, sonra sadece bir cpp veya ino dosyasında tanımlayın. Her zamanki yol, 1) FastLedInclude.h dosyasında extern struct CRGB ledlerini []; yazmaktır. 2) bir ino veya cpp dosyası seçin (muhtemelen ana ino dosyası en çok belirtilen değil, fakat çalışmalı) ve struct CRGB ledlerini [NUM_LEDS] yazmalı; . Bu işe yaramazsa, kodunuzu gönderin ve ona bir göz atmaya çalışacağım
katma yazar Tom Collins, kaynak
Cevabı daha fazla örnekle ekledim ..
katma yazar Tom Collins, kaynak
Bu benim kütüphanemde kendi fastLED taslaklarını kullanan birinin ana çizimden kendi proje boyutunu tanımlayamayacağı için işe yaramaz. Anladığımdan emin olmak için sorumu değiştireceğim.
katma yazar Slacker, kaynak
Bu çok yararlı. Kullanıcıdan, const byte numberOfLeds = NUM_LEDS 'i skriptine eklemesini ve NUM_LEDS yerine benim kütüphanemde numberOfLeds kullanmasını isteyebilir miyim? ?
katma yazar Slacker, kaynak
ve sonra kitaplık başlığımda const byte numberOfLeds öğesine bir işaretçi ekleyin?
katma yazar Slacker, kaynak
Bu çok yararlı, çok teşekkürler. İlk önerdiğiniz #include "FastLedInclude.h" sürümünü uygulamaya çalıştım ve bu sorudaki tüm bilgileri vermediğimi fark ettim. FastLED kurulumunun, kodun kullanıldığı sayfalara struct CRGB ledlerini [NUM_LEDS]; eklemem gerekiyor. Bunu FastLedInclude.h içine eklerseniz bir derleme hatası alırım 'leds' çoklu tanımı
katma yazar Slacker, kaynak
Cpp dosyalarımda struct CRGB ledlerini [NUM_LEDS]; ve ana kodda extern CRGB * leds; kullanmayı denedim, ancak program çalışmıyor.
katma yazar Slacker, kaynak
Bu mükemmel çalışıyor! Yardımınız için çok teşekkür ederim, buna 'cevap' olarak katkıda bulunmaktan çekinmeyin
katma yazar Slacker, kaynak

1 cevap

OP'nin önerdiği gibi, cevabın bulunduğundan beri kendi sorusu altındaki yorumların bir özetini yayınlıyorum.

Farklı kaynak dosyalarındaki bu parametreler için ortak bir tanım yapmak için en kolay çözüm, paylaşılan bir başlık oluşturmaktır. Bunu yapmak için FastLedInclude.h adlı yeni bir dosya oluşturmanız yeterlidir.

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

Daha sonra her kaynak dosyasında, bu kütüphaneyi kullanabilmek için #include "FastLedInclude.h" 'a sahip olmanız yeterlidir.

FastLED kitaplığı ayrıca programcının bir yapı oluşturmasını gerektirir. Şimdi, derleyici, her bir nesne dosyası için bir kez tahsis etmek için kod yazdığı için, yapının tanımını (ör. struct CRGB ledleri [NUM_LEDS]; ) başlık dosyasına yerleştirmek derleme hatalarına yol açar.

Bunu farklı nesne dosyaları arasında paylaşmanın doğru yolu, başlıkta extern 'i belirtmek ve daha sonra cpp veya ino dosyalarından birinde bir kez tanımlamaktır:

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

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

Bu, ana ino çizim dosyasında da yapılabilir, ancak kişisel olarak bunu başka bir tanımlı olarak tanımlamayı tercih ederim (ancak, programı nasıl böldüğünüze bağlıdır).

Bir kütüphane oluşturmak istiyorsanız, başka problemler ortaya çıkar. En kolay çözüm, kullanıcının kütüphane klasöründe olacak olan başlık dosyasını manuel olarak değiştirmesini istemektir. Bu çözüm biraz rahatsız edici, ama en güvenli olanı.

Başka bir çözüm ise, kullanıcıyı eskiz dosyasına bir başlık dosyası oluşturmaya zorlamaktır. Daha sonra kütüphane, arka planı içerecek eskiz klasör yolunu bilmelidir. Ama .. Bu çok cesaretsiz bir seçenek, çünkü kütüphanenin çizim yerini bilmesi ve böylece kütüphane tabanlı bir yaklaşımın temelinde tutarlılık ilkesini ihlal etmesi gerekecek.

Üçüncü çözüm, bir derleme zamanı statik tanımından dinamik olana yaklaşımı değiştirmektir. Bunu yapmak için, derleme zamanında NUM_LEDS ve DATA_PIN tanımlamak yerine, bunları kitaplık sınıfındaki değişkenler olarak kaydedersiniz.

Örneğin, kitaplık sınıf tanımınızda

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

Ve uygulama olabilir

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

Sonra kullanıcı yazabilir

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

veya statik olarak ayrılmış bir nesne durumunda,

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
katma
Süper teşekkürler! Bu harika bir cevap :)
katma yazar Slacker, kaynak