3

Arduinoでライブラリを作り始めたばかりです。inSerialCmd という名前のライブラリを作成しました。inSerialCmd ライブラリがインクルードされた後、メイン プログラム ファイルstackedcontrol.ino で定義されている delegate() という名前の関数を呼び出したいと考えています。

コンパイルしようとすると、1 つのエラーがスローされます。

...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: メンバー関数 'void inSerialCmd::serialListen()': ...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: エラー: 'delegate' はありません宣言された

少し検索した後、スコープ解決演算子を追加するとうまくいくように見えました。そのため、delegate() の前に "::" を追加し、現在は "::delegate()" を追加しましたが、同じエラーがスローされます。

今、私は困惑しています。

4

1 に答える 1

7

ライブラリからプログラム内の関数を直接呼び出すことはできませんし、そうすべきではありません。ライブラリをライブラリにする重要な側面に注意してください。

ライブラリは特定のアプリケーションに依存しません。プログラムが存在しなくても、ライブラリを完全にコンパイルして .a ファイルにパッケージ化できます。

したがって、一方向の依存関係があり、プログラムはライブラリに依存します。一見すると、これはあなたが望むものを達成するのを妨げているように見えるかもしれません. コールバックと呼ばれることもある機能を使用して、求めている機能を実現できます。メインプログラムは、実行時に実行する関数へのポインタをライブラリに提供します。

// in program somwehere
int myDelegate(int a, int b);

// you set this to the library
setDelegate( myDelegate );

割り込みハンドラがどのようにインストールされているかを見ると、arduino でこれがわかります。これと同じ概念が多くの環境 (イベント リスナー、アクション アダプター) に存在し、ライブラリが認識できない特定のアクションをプログラムが定義できるようにするという同じ目標をすべて持っています。

ライブラリは、関数ポインタを介して関数を格納および呼び出します。これがどのように見えるかの大まかなスケッチは次のとおりです。

// in the main program
int someAction(int t1, int t2) {
  return 1;
}

/* in library
this is the delegate function pointer
a function that takes two int's and returns an int */
int (*fpAction)(int, int) = 0;   

/* in library
this is how an application registers its action */
void setDelegate( int (*fp)(int,int) ) {
  fpAction = fp; 
}

/* in libary
this is how the library can safely execute the action */
int doAction(int t1, int t2) {
  int r;
  if( 0 != fpAction ) {
    r = (*fpAction)(t1,t2);
  }
  else {
    // some error or default action here
    r = 0;
  }
  return r;
}

/* in program
The main program installs its delegate, likely in setup() */
void setup () {
  ...      
  setDelegate(someAction);
  ...
于 2013-01-20T20:28:50.587 に答える