#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ライブラリを使用しています.LEDの数がメインスケッチの値を変更するだけで制御できるように、オブジェクトごとに異なるヘッダーファイルでNUM_LEDSを参照できるようにしたいと考えています。

自分のオブジェクトを他の人が使用できるように図書館にすることもできるようにするため、図書館で使用する設定をメインスケッチで定義します。

0
確かに..これらの3つの行(例えば、 FastLedInclude.h )を含むヘッダーファイルを作成し、FastLedライブラリが必要な各ファイルで、 #include "FastLedIncludeを記述します。 #include の代わりに "h"
追加された 著者 Tom Collins,
コンパイルするすべてのファイルにNUM_LEDSを定義する必要があります。そのため、すべてのcppまたはinoファイルにインクルードするためにヘッダーファイルに必要となります。今、あなたがライブラリを作りたいなら、そのファイルは1)ライブラリフォルダか2)スケッチフォルダのどちらかになければなりません。 2番目のアプローチは、IMHOです。ユーザーがスケッチフォルダにファイルを作成する必要があり、スケッチの場所を知る必要があります。ライブラリの定義に反します。つまり、それ自身で動作することができます。私の個人的なアドバイスは、ライブラリファイルを変更するようにユーザーに依頼することです。
追加された 著者 Tom Collins,
コンパイル時の静的割り当ての代わりに動的割り当てを使用してコードを編集するよう強制することができます。つまり、 DATA_PIN を定義する代わりに、データピンを含むクラスにuint8_t変数を格納することができます。 NUM_LEDS で同じことができますし、コード内に動的に( malloc sまたは new パフォーマンスは低下する可能性がありますが、より効果的です
追加された 著者 Tom Collins,
あなたの図書館には少なくとも1つのクラスが含まれていますね。したがって、変数をクラスに格納してから、その変数をpublic(悪い)またはprivate(より良い)にしてコンストラクタで設定することができます。したがって、ユーザは、あなたのオブジェクトを動的に割り当てる必要があります。 yourclass * obj = new yourclass(60); (または、 #define NUM_LEDS 60 > class> obj = new yourclass(NUM_LEDS); )または静的に yourclass obj(60); (または yourclass obj(NUM_LEDS);どちらの場合でも、オブジェクトに値が格納されます
追加された 著者 Tom Collins,
もちろん、ヘッダーに変数を定義することはできません。そうしないと、変数を複数回定義することができます。あなたは間違いなくそれを宣言することができ、extern宣言してから、それを1つのcppまたはinoファイルで定義する必要があります。通常の方法は、1) extern struct CRGB leds []; をFastLedInclude.hファイルに書き込むことです。 2)inoファイルまたはcppファイルを選択してください(主なinoファイルはほとんど表示されませんが、動作するはずです)、 CRGB led [NUM_LEDS]; を記述してください。これでうまくいかない場合は、コードを投稿してみてください。
追加された 著者 Tom Collins,
私はいくつかの例で答えを追加しました..
追加された 著者 Tom Collins,
自分のfastLEDスケッチで自分のライブラリを使用している人がメインスケッチから独自のプロジェクトサイズを定義することができないため、これは機能しません。私は自分の質問を変えて、それが理解されていることを確認します。
追加された 著者 Slacker,
それはとても役に立ちます。 NUM_LEDS ではなく、 const byte numberOfLeds = NUM​​_LEDS をスケッチに追加してから numberOfLeds を使用するように、 ?
追加された 著者 Slacker,
ライブラリヘッダの const byte numberOfLeds にポインタを追加しますか?
追加された 著者 Slacker,
これは非常に役に立ち、多くのおかげです。あなたが最初に提案した #include "FastLedInclude.h" のバージョンを実装しようとしましたが、私は質問のすべての情報を提供していないことに気付きました。 FastLEDの設定では、コードが使用されているページに struct CRGB leds [NUM_LEDS]; を追加する必要があります。 FastLedInclude.h にそれを含めると、 'leds'の複数定義というコンパイルエラーが発生します。
追加された 著者 Slacker,
私は私のcppファイルの extern CRGB * leds; の中で struct CRGB leds [NUM_LEDS]; を使ってみましたが、プログラムは動作しません
追加された 著者 Slacker,
これは完全に動作します!ご協力いただきありがとうございます。これを「回答」として寄付してください。
追加された 著者 Slacker,

1 答え

OPが示唆したように、私は答えが見つかったので、彼の質問の下にコメントの集計を掲示しています。

異なるソースファイルでこれらのパラメータを共通に定義するには、最も簡単な解決策は共有ヘッダーを作成することです。これを行うには、 FastLedInclude.h という新しいファイルを作成し、その中に

#include 
#define NUM_LEDS 60
#define DATA_PIN 6

次に、すべてのソースファイルで、そのライブラリを使用できるようにするには #include "FastLedInclude.h" するだけです。

FastLEDライブラリでは、プログラマが構造体を作成する必要があります。これで、ヘッダファイルに構造体の定義(つまり、 struct CRGB leds [NUM_LEDS]; )を配置すると、コンパイラはオブジェクトファイルごとにコードを1回割り当てます。

異なるオブジェクトファイル間でこれを共有する正しい方法は、ヘッダーに extern を宣言してから、cppまたはinoファイルのいずれかで一度だけ定義することです。

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

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

これはメインのinoスケッチファイルでも行うことができますが、私は個人的に別のプログラムに定義する方が好みです(ただし、プログラムの分割方法によって異なります)。

ライブラリを作成したい場合は、他のいくつかの問題が発生します。最も簡単な解決策は、ライブラリフォルダ内にあるヘッダファイルを手動で変更するようにユーザに依頼することです。このソリューションは少し不快ですが、最も安全なソリューションです。

もう1つの解決策は、ユーザにスケッチフォルダにヘッダファイルを作成させることです。ライブラリはスケッチフォルダのパスを知っていなければなりません。しかし、これはライブラリがスケッチの場所を知る必要があり、ライブラリベースのアプローチの根底にある一貫性の原則に違反するため、非常に落胆した選択肢です。

3番目の解決方法は、コンパイル時の静的な定義から動的な静的な定義にアプローチを変更することです。これを行うには、コンパイル時に NUM_LEDSDATA_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,