2

私はarduinoとプログラミングの初心者です。arduino の独自のライブラリ内にライブラリを含めましたが、最初のライブラリには、パラメーターとしてポインター関数を持つ関数が含まれています。これは割り込みサービス ルーチン (ISR) ですが、割り込みが発生したときに cpp ファイルで関数を呼び出す必要があります。したがって、その関数のポインタを最初のライブラリ コードに渡す必要があります。.ino ファイルで使用するとうまく機能します。次のように渡すことができます。

attachInterrupt(functionISR_name);

しかし、.cpp ファイルで使用すると、エラーが発生します。私の機能は、

void velocity::functionISR_name(){
//some code
}

しかし、この関数のポインタを最初のライブラリ関数に渡すにはどうすればよいですか? この方法で試してみましたが、エラーが発生しました。

attachInterrupt(velocity::functionISR_name);
4

2 に答える 2

3

静的に定義しない限り、関数を期待する関数にメソッドを渡すことはできません。

静的に書きます:

static void velocity::functionISR_name() 

attachInterrupt(&velocity::functionISR_name);

残念ながら、静的メソッドは特定のインスタンスにバインドされなくなりました。シングルトンと一緒にのみ使用してください。Arduino では、抜粋したコードで以下に示すようなクラスを作成する必要があります。

class velocity
{
    static velocity *pThisSingelton;
 public:
    velocity()
    {
      pThisSingelton=this;
    }

    static void functionISR_name()
    {
      pThisSingelton->CallWhatEverMethodYouNeeded();
      // Do whatever needed.
    }

   // … Your methods
};

velocity *velocity::pThisSingelton;
velocity YourOneAndOnlyInstanceOfThisClass;

void setup()
{
  attachInterrupt(&velocity::functionISR_name);

  // …other stuff…
}

これは見栄えが悪いですが、私の意見では、このようなシステムでは機会が非常に限られているため、Arduino ではまったく問題ありません。

もう一度考えてみると、私は個人的に、ソリンが上記の回答で言及したアプローチを採用します。それはもっと似ているでしょう:

class velocity
{
 public:
    velocity()
    {
    }

    static void functionISR_name()
    {
      // Do whatever needed.
    }

   // … Your methods
};

velocity YourOneAndOnlyInstanceOfThisClass;

void functionISR_name_delegation()
{
  YourOneAndOnlyInstanceOfThisClass.functionISR_name();
}

void setup()
{
  attachInterrupt(functionISR_name_delegation);

  // …other stuff…
}

また、最初の例で必要なポインター用に数バイト節約できます。

サイト ノートとして: 将来のために、正確なコードを投稿し (たとえば、attachInterrupt にはよ​​り多くのパラメーターが必要)、エラー メッセージをコピーして貼り付けてください。通常、エラーはあなたが疑わない場所で正確です。この質問は例外でした。通常、私と他の人はより良い仕様を求めます。

于 2013-10-05T08:46:54.450 に答える
1

関数へのポインターを渡しますが、関数はクラス メンバーです。ポインターがガベージになるため、呼び出しが無効になる可能性がthisあります (正常にコンパイルされる可能性がありますが、実行時に奇妙なエラーがスローされます)。

クラスの外でプレーンなバニラ関数を定義し、それを使用する必要があります。非常に複雑なプロジェクトがない場合は、使用する必要があるクラス インスタンスへのグローバル ポインターを使用して、新しい関数で呼び出しをデリゲートするだけで済みます。正しい方法で処理したい場合は、上で説明したインスタンス ポインターを取得するメカニズムが必要です。通常、これにはシングルトンまたはいくつかのファクトリ パターンが含まれます。

例:

class Foo {
  void method() {
    x = 5;
  }
  int x;
}

メソッドにコールバックがあると、無効なポインターがあるためクラッシュthisx=5、メモリ内のどこかにランダムに 5 が書き込まれます。必要なものは次のようなものです:

static Foo* foo_instance;  // Initialized somewhere else.
void method_delegator() {
  foo_instance->method();
}

これで、関数に渡すことができmethod_delegatorます。ポインターも渡すようになっfoo_instanceたため、機能します。this

于 2013-10-05T08:43:35.877 に答える