0

我正在编写一个 Arduino 应用程序(在 VSCode 中使用 platformIO),并包括一个外部 CAN 库(FlexCAN_T4)。我想在一个单独的文件(protocol.cpp)中定义我所有的协议/消息处理程序回调,并从我的主文件(main.cpp)中引用它们。所以我用我所有的函数签名创建了一个头文件(protocol.h),并包含来自protocol.cpp和main.cpp的protocol.h。

但是我得到了“'flexcan_isr_can1()'的多重定义”(这是一个在引用库 FlexCAN_T4 中定义的函数)。我无法弄清楚如何摆脱这个错误,并且仍然拥有我所有的函数签名和常量以及无法正常工作的东西。

示例错误消息(FlexCan_T4.h 中定义的每个非类函数一个):

.pio/build/teensy40/src/protocol.cpp.o: In function `flexcan_isr_can1()':
protocol.cpp:(.text._Z16flexcan_isr_can1v+0x0): multiple definition of `flexcan_isr_can1()'
.pio/build/teensy40/src/main.cpp.o:main.cpp:(.text._Z16flexcan_isr_can1v+0x0): first defined here
/Users/pdesrosiers/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Disabling relaxation: it will not work with multiple definitions

协议.h

#pragma once
#include <FlexCAN_T4.h>
const uint8_t myConst = 100;
extern FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> flexCAN;

void myFunction();

协议.cpp

#include "protocol.h"
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> flexCAN;

void myFunction()
{
    //one of a hundred functions related to protocol, that should be defined outside of main.cpp.
    flexCan.doSomething(myConst);
}

主文件

#include "protocol.h"
#include <Arduino.h>

void setup()
{
  //some setup stuff...
}

void loop()
{
  myFunction();
}

从某种意义上说,这些错误是有道理的,因为 protocol.h(以及,可传递的,FlexCAN_T4.h)被多次#included。

但是我怎样才能保持这种良好的代码组织,我的回调在 main.cpp 之外定义?包含这些依赖项的正确方法是什么?

4

3 回答 3

0

问题在于flexcan_isr_can1(和其他函数)是在包含在多个翻译单元中的头文件中定义的。这违反了单一定义规则。相关的函数定义应该inline添加关键字。


这是 FlexCAN_T4 库中的一个缺陷;您应该将问题提交给图书馆的维护者。

于 2019-09-30T05:31:01.790 回答
0

我已经包含了守卫,比 #pragma 更推荐一次,并且总是在 H 文件中:

#if !defined(_FLEXCAN_T4_H_)
#define _FLEXCAN_T4_H_

您声称看到的缺陷在哪里?

于 2019-10-14T01:49:26.600 回答
0

如果在protocol.h 中不需要FlexCAN_T4 相关部分,您可以将它们放在cpp 文件中。比如去掉以下部分,放到protocol.cpp中:

包括

外部 FlexCAN_T4 flexCAN;

于 2019-09-30T04:39:08.910 回答