从Arduino库中调用主程序中的函数

3
我刚开始在Arduino中制作库。我已经制作了一个名为inSerialCmd的库。当我导入inSerialCmd库后,我想调用在主程序文件stackedcontrol.ino中定义的函数delegate()。
但是,在编译时,会出现以下错误:
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: In member function 'void inSerialCmd::serialListen()': ...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: error: 'delegate' has not been declared
经过一番搜索后,似乎加上范围解析运算符可以解决问题。所以我添加了"::"到delegate()前面,即"::delegate()",但是还是出现相同的错误。
现在我感到很困惑。
1个回答

8
您不能直接从库中调用程序中的函数,也不应该这样做。请记住,使库成为库的一个关键方面是:

库不依赖于特定的应用程序。可以将库完全编译并打包到 .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);
  ...

1
谢谢!这使得事情更加清晰。我会研究函数指针。 - Blair Kelly
应该是 setDelegate(someAction); 吧? - Hayden Thring
@jdr5ca,这是一个非常好的答案,是最好的之一。希望我能为您贡献积分。 - Curnelious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接