【问题标题】:How do I add cpp file to an arduino project?如何将 cpp 文件添加到 arduino 项目?
【发布时间】:2019-09-05 03:38:20
【问题描述】:

我正在尝试将 cpp 文件添加到具有以下设置的 arduino 项目...

project 
--folder
  --foo.h
  --foo.cpp
--project.ino

我在project.ino 的顶部有一个#include "folder/foo.h。然而,虽然头文件提供了函数的原型,但函数定义在 cpp 文件中。当我尝试使用 Arduino IDE 编译代码时,它失败并出现错误 Undefined reference to 'bar()'bar() 位于foo.cpp

我查看了this,但我没有sketch/import library 的设置(但是我有sketch/include library,但是我没有看到任何接近使用自定义文件夹位置的东西)

我也看了this。但和上面一样,我的 ide 中不存在该设置。 (我最近下载的)

代码

//project.ino
#include "folder/foo.h"
void setup() {
    Serial.begin(9600);
}
void loop() {
    bar();
}
//folder/foo.h
#include "Arduino.h"
void bar();
//folder/foo.cpp
#include "foo.h"

void bar() {
    Serial.println("bar");
}

错误

/tmp/ccNTRFfU.ltrans0.ltrans.o: In function `loop':
/home/temporary/project/project.ino:9: undefined reference  to `bar()'
collect2: error: ld returned 1 exit status
exit status 1

我期望发生的是一种链接 cpp 文件夹的方法,而无需将所有文件放在项目的同一根文件夹中。

--编辑1: 添加代码

--编辑2: 已添加#include "Arduino.h"

--编辑3: 已添加Serial.begin(9600);

【问题讨论】:

  • 请在此处显示minimal reproducible example 以重现您的问题。确保bar()foo.h 中声明的签名完全相同。
  • 在项目中为每个文件打开一个选项卡。您可以创建一个新文件或将现有文件导入到您的项目中。
  • 如果您按照上面的要求添加一个完整且可验证的示例,我会支持这个问题。
  • @GabrielStaples,已添加。
  • 我刚刚提出了您的问题,因为它已经完成并且包含准确复制它所需的所有部分。我不知道你为什么又被否决了。当您的问题没有代码时,第一个是有意义的。最后一个没有意义。现在这是一个很好的、可靠的问题。干得好。

标签: c++ arduino arduino-ide


【解决方案1】:

如何在您的 Arduino 项目中正确包含 C/C++ 头文件和源文件。

这个答案已经过测试和编译,以确保它有效。(在带有 Arduino 1.8.7 IDE 的 Linux Ubuntu 中完成)。

你有 2 个问题。

第一个: Arduino 不寻常的构建过程 (described here) 不允许包含来自您的项目目录中的子文件夹,您的项目目录中的 .ino 文件所在的位置。

[更新:当我在 PC 上复制您的代码时,这可能只是我的错误,而不是您的错误:我不小心使用了 foo.c 而不是 foo.cpp]
2nd: C++ 只能在 C++ 源文件中使用,因此您必须将 foo.c 更改为 foo.cpp,因为 Serial.println() 是对 C++ 类 (Serial) 的 C++ 调用println() 方法。

要修复 1,只需更改文件夹结构,将所有内容都放在一个文件夹中:

project
├── foo.cpp
├── foo.hh
└── project.ino

我也为下面的 #1 提供了一个替代修复。

要修复 2,(这是强制性的!)make foo.c --> foo.cpp 和(可选,但建议显示它是 C++ 头文件)foo.h - ->foo.hh。现在也将 .ino 和 .cpp 文件中的包含更新为 #include "foo.hh"

就是这样!现在关闭 Arduino IDE,然后重新打开它并重新打开您的项目,您将看到以下新选项卡出现:

现在编译就好了!

学习:我是如何发现这一点的?

首先,在 Arduino IDE 中开启详细编译:File --> Preferences --> 勾选“Show verbose output during 'compilation'”。

现在,当您编译时,所有错误都将显示在 IDE 窗口的底部,以及引发错误的 exact 编译或链接命令。

一旦我修复了文件夹结构,但您的文件仍然是 C 而不是 C++ 文件,我看到了这个错误:

Compiling sketch...
/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -I/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/arduino/avr/cores/arduino -I/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/arduino/avr/variants/eightanaloginputs /tmp/arduino_build_233569/sketch/foo.c -o /tmp/arduino_build_233569/sketch/foo.c.o
/tmp/arduino_build_233569/sketch/foo.c: In function 'bar':
foo.c:9:5: error: 'Serial' undeclared (first use in this function)
     Serial.println("bar");
     ^
/tmp/arduino_build_233569/sketch/foo.c:9:5: note: each undeclared identifier is reported only once for each function it appears in
exit status 1
'Serial' undeclared (first use in this function)

请注意,它未能编译的文件是 /tmp/arduino_build_233569/sketch/foo.c,并且当时正在使用 avr-gcc C 编译器(而不是 avr-g++ C++ 编译器)。

然后我打开了/tmp/arduino_build_233569/sketch/foo.c 文件来检查它并寻找它的异常之处。

接下来,我使用 Eclipse 开始跟踪包含,以查看Serial 被拉入的位置(对我来说问题应该已经很明显了,但我还没有看到它)。我发现了以下内容:

Arduino.h 位于“Arduino/Source/Arduino/hardware/arduino/avr/cores/arduino/Arduino.h”中。它包括"HardwareSerial.h"。这个标头externs 是Serial 对象:

#if defined(UBRRH) || defined(UBRR0H)
  extern HardwareSerial Serial;
  #define HAVE_HWSERIAL0
#endif

但是,回顾Arduino.h,您会发现HardwareSerial.h 仅在您使用C++ 编译时才包含:

#ifdef __cplusplus   <========= This means that the following headers are ONLY included if you are compiling with C++! BOOM! That's when it hit me! You're compiling a C file with the C compiler to access a C++ object. That's not ok. Use the C++ compiler!
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "USBAPI.h"
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
#error "Targets with both UART0 and CDC serial not supported"
#endif

#ifdef __cplusplus 表示仅当您使用 C++ 编译时才包含上面的标头!就在那时它击中了我!您正在使用 C 编译器编译 C 文件以访问 C++ 对象。那不行。您必须改用 C++ 编译器。只需将foo.c 更改为foo.cpp 即可。完成。

解决您的问题 #1(文件夹结构)的替代方法:

从 Arduino IDE 中找到您的“Sketchbook 位置”:文件 --> 首选项。例如,我的是/home/gabriel/dev/Arduino/Sketches

现在,去那里创建一个“库”文件夹。对我来说,现在是/home/gabriel/dev/Arduino/Sketches/libraries。此文件夹中的所有内容现在都被视为 Arduino“库”,并且可以包含在内。将foo.h [在这种情况下不要使用foo.hh] 和foo.cpp 移动到那里,像这样:

/home/gabriel/dev/Arduino/Sketches/libraries/foo
├── foo.cpp
└── foo.h     <==== NOT foo.hh in this case!

现在关闭并重新打开 Arduino IDE,然后转到 Sketch --> Include Library --> foo,它会自动为您添加以下行:

#include <foo.h>

在这种情况下您不能使用 foo.hh 的原因仅仅是因为 Arduino 仅在您添加库时才在寻找 .h 文件,包括以这种方式使用菜单。 就我而言,这是一个错误,可能应该报告给 Ar​​duino 开发人员。请随意接受。

附录:

2019 年 4 月 16 日:
google search for "arduino add include path" 将我引向这个:https://forum.arduino.cc/index.php?topic=445230.0,其中用户 @pert 说:

在最新版本的 Arduino IDE(包括 1.6.10)中,如果您想从草图文件夹中包含库,您需要将它们放在 src 子文件夹中。例如:

Blink  
|_Blink.ino  
|_src  
   |_BlinkLib  
       |_BlinkLib.h  

然后他说你可以像这样包含:

#include "src/BlinkLib/BlinkLib.h"  

我还没有尝试过,但如果它有效,那将非常有用。试一试,让我知道它是否有效。请务必告诉我们您使用的是哪个操作系统和 Arduino IDE 版本。

另见:

  1. 在 Github 上的其他讨论:https://github.com/arduino/Arduino/issues/5186
  2. 这里是官方 Arduino 库规范:https://arduino.github.io/arduino-cli/latest/library-specification/

【讨论】:

  • 为什么在本地包含文件时使用 .hh 而不是 .h?另外,#include "project/foo.cpp" 呢?那似乎已经编译了 并运行了 。这让我觉得,扩展程序没有得到检查。
  • .hh 而不是 .h 只是个人偏好将 C++ 标头标记为 C++ 标头。只要你是一致的,你使用什么并不重要。在工作中,我们使用 .h 表示 C 头文件,使用 .hh 表示 C++ 头文件,使用 .c 表示 C 源文件,使用 .cc 表示 C++ 源文件。其他常用的扩展名包括用于 C++ 头文件的 .hpp 或 .h++,以及用于 C++ 源文件的 .cpp 或 .c++。见这里:stackoverflow.com/questions/5171502/…。至于#include "project/foo.cpp" 工作,我不能说,但我怀疑你关于未检查完整路径的想法是正确的。
  • 我刚刚在我的答案底部添加了一个附录。尝试将子文件放在项目文件夹内的src 文件夹中,如果效果好,请报告。
【解决方案2】:

在您的项目中为每个文件打开一个选项卡。 您可以创建一个新文件或将现有文件导入到您的项目中。 这样您就可以使用多个*.ino*.c*.cpp*.h 文件。我没有找到导入本地目录或配置项目结构的方法。

【讨论】:

    【解决方案3】:
    1. 将您的folder 放在libraries 文件夹中,该文件夹是您的速写本目录的子目录。
    2. 打开 Arduino IDE(如果已打开,请退出并重新打开)。
    3. 转到Sketch-&gt;Include Library。您将在Contributed Libraries 部分下找到folder
    4. 选择folder,一切顺利。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-17
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      相关资源
      最近更新 更多