我正在尝试根据代码是否创建对象(或调用函数等)来禁用某些代码。听起来有些奇怪,我知道。
在我的库中可以创建2个对象,每个对象都需要一个中断服务程序,例如:
ISR(TIMER0_COMPA_vect) {
// do some stuff if the interrupt happens
}
ISR只能创建一次,但是用户可能只创建一个对象或不创建任何对象,因此,不应首先创建ISR,以免用户阻塞一个对象的创建。 我知道封装这样的代码会很容易
#ifdef OBJECT1
ISR(TIMER0_COMPA_vect) {
// do some stuff if the interrupt happens
}
#endif
但是这迫使用户跟踪她/他创建的对象。 是否可以让预处理器决定是否调用构造函数一次或什至不存在? 有点像这样
Foo:Foo() {
#define USE_FOO
//Some code
}
#ifdef USE_FOO
ISR(TIMER0_COMPA_vect) {
// do some stuff if the interrupt happens
}
#endif
编辑:
根据我得到的答案,我尝试澄清一下我的问题:
Foo1:Foo1() {
//Some object constructor code
}
Foo2:Foo2() {
//Some object constructor code
}
ISR(TIMER1_COMPA_vect) {
//some interrupt code
}
ISR(TIMER2_COMPA_vect) {
//some interrupt code
}
int main() {
Foo2 foo2;
}
如果这是我们正在讨论的代码,则根本不应该编译函数ISR(TIMER1_COMPA_vect)。必须缺少ISR。
PS:如果您需要更多信息,我可以提供更多信息,但是我尝试将问题保持在尽可能基本的状态
答案 0 :(得分:1)
通常,针对这种情况的处理方式是将此类对象的代码编译到库中。链接器足够聪明,可以检测您的主程序是否依赖于库中的任何函数。如果是这样,它将把该函数的整个编译单元(即.c或.cpp文件)加载到您的程序中。它在编译单元中找到的所有ISR都将添加到您的程序中。如果您不使用该库中的任何功能,则不会添加ISR。
例如,在foo1.h中放入如下内容:
#pragma once
class Foo1 {
public:
Foo1();
};
在foo1.cpp中放入以下内容:
#include <foo1.h>
ISR(TIMER1_COMPA_vect) {
}
Foo1::Foo1() {
}
现在,您应该使用foo1.cpp
将foo1.o
编译成avr-gcc
。接下来,使用avr-ar
将foo1.o
存储在名为foo1.a
的档案中。然后,使用avr-gcc
编译主程序,并提供foo1.a
作为参数。确保foo1.a
参数位于main.cpp
之后。
答案 1 :(得分:0)
正如您所说,您的问题听起来很奇怪,但是如果您只想做一次,让我们说在构造函数中,您可以使用局部静态变量来处理像这样的简单但非常丑陋的事情
Foo:Foo() {
static bool init = true;
if( init ) {
//Some code for ISR init
init = false;
}
}
这样,无论您或您的用户构造的Foo对象有多少,您的特殊ISR初始化都只会发生一次
编辑:
我认为没有办法实现自己想要的,至少没有干净的办法。
Imo,您的问题来自您的ISR宏,它实际上有两件事:
要解决您的问题,建议您将其拆分为两个宏,然后:
然后,您的处理程序将保持定义状态,并且如果未由任何Foo类注册,则该处理程序将不受影响
答案 2 :(得分:0)
您可能需要创建一个单例。有很多例子。单例是只构造一次的类。构造函数是私有的,静态方法将检查“全局”变量,以查看是否已经构造了该类(如果没有构造,它将仅构造一次)。您可能需要考虑线程问题,尽管对于构造而言,您可以在创建多个类之前简单地引用该类。对于一个中断的多个用户,您通常使用某种分配器,这些对象向其注册,然后调用对该中断感兴趣的所有类。调度程序可以是单例。通常,调度程序的客户端会实现一个接口。作为向调度程序注册的一部分,该类告诉调度程序其“ this”指针,并且调度程序可以调用从接口实现的方法,就像它们被正常调用一样。客户端不需要具有静态方法。这些东西可能有模式,但我无法命名。