首页 > 解决方案 > 如何在我自己的 Arduino 库中使用外部库?

问题描述

晚上好!

我正在写一个 Arduino 库。在其中,我想从另一个库中实例化一个对象,该库的构造函数需要传递一个参数,但我不想硬编码这样的参数。我需要一些关于如何做到这一点的指导。

到目前为止,这是我的代码的相关部分:

汇丰银行_CAN.h:

class HSBC_CAN {

    public:
        HSBC_CAN(uint8_t, uint8_t);

    private:
        uint8_t _int_pin;

};

HSBC_CAN.cpp:

#include <HSBC_CAN.h>
#include <mcp_can.h>

extern MCP_CAN *canbus_esc;

HSBC_CAN::HSBC_CAN(uint8_t int_pin, uint8_t cs_pin) {

    _int_pin = int_pin;
    canbus_esc = new MCP_CAN(cs_pin);

}

需要明确的是,从 MCP_CAN 类中实例化对象的方法是MCP_CAN foo(int bar),其中bar是 SPI 协议的片选引脚号。我希望我的库实例化 MCP_CAN 类的对象,但在从我的新类 HSBC_CAN 实例化对象时,我需要能够传递芯片选择引脚号。这是我使用上面的代码得到的错误:

error: request for member 'begin' in 'canbus_esc', which is of pointer type 'MCP_CAN*' (maybe you meant to use '->' ?)

可能我在示例代码中所做的方式是完全错误的(使用extern关键字和new运算符),但这正是我脑海中 ATM 的结果。

谢谢你的时间。

标签: c++arduinoavrhardware-programming

解决方案


来自编译器的错误消息非常有用,如果您按照它的建议替换.->可能会解决您的直接问题。由于canbus_esc是一个指针,因此您必须在访问其成员或函数之前取消引用它。因此,如果它有一个begin可以用零参数调用的函数,你可以这样写:

canbus_esc->begin();

该行相当于:

(*canbus_esc).begin();

另外,去掉extern定义行上的单词canbus_esc,否则你会得到一个未定义的引用错误。

但是,您提供的代码有两个问题:首先,您使用new的是动态内存分配。如果可以的话,最好避免在像 AVR 这样的小型设备上进行动态内存分配,因为在实际运行程序之前,您永远不知道这些分配是否会失败(您可能在程序的其他部分使用了太多内存)。其次,您canbus_esc在文件范围内定义了您的文件,因此只能是其中一个。这意味着您不能真正创建多个HSBC_CAN对象。第二个将覆盖第一个canbus_esc创建的。尽管这对您的应用程序来说可能没问题,但这似乎是一个不必要的限制。

我建议改为这样编写您的代码:

头文件:

#include <mcp_can.h>
class HSBC_CAN {
public:
  HSBC_CAN(uint8_t int_pin, uint8_t cs_pin);
  void begin();
private:
  uint8_t _int_pin;
  MCP_CAN can;
};

源文件:

#include <HSBC_CAN.h>

HSBC_CAN::HSBC_CAN(uint8_t int_pin, uint8_t cs_pin)
  : can(cs_pin)  // This line constructs the MCP_CAN object
{
  _int_pin = int_pin;
}

HSBC_CAN::begin()
{
  can.begin(42, 42, 42);  // TODO: fix arguments
}

另一个可能更好的想法是让您的 HSBC_CAN 对象获取指向 MBC_CAN 对象的指针并将指针作为成员变量存储在 HSBC_CAN 类中。如果您想使用 MBC_CAN 对象与 CAN 总线上的多个设备进行通信,那么该选项将很有意义。您可以通过指针使用单个 MBC_CAN 对象来创建多个类。


推荐阅读