如何将cpp文件添加到arduino项目?

时间:2019-04-15 07:30:08

标签: c++ arduino arduino-ide

我正在尝试向具有以下设置的arduino项目中添加一个cpp文件...

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

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

我查看了this,但是没有sketch/import library的设置(但是我有sketch/include library,但是看不到任何使用自定义文件夹位置的内容)< / p>

我也看着this。但是与上面相同,我的想法中不存在该设置。 (我最近下载了哪个)

代码

//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);

3 个答案:

答案 0 :(得分:1)

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

此答案已经过测试和编译,以确保其有效。(已在Linux Ubuntu中使用Arduino 1.8.7 IDE完成)。

您有2个问题。

第一个::Arduino的异常生成过程(described here)不允许在项目目录的.ino文件所在的项目目录中包含子文件夹。

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

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

println()

我也为下面的#1提供了替代解决方案。

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

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

enter image description here

现在可以编译了!

学习:我如何解决这个问题?

首先,在Arduino IDE中打开详细编译:文件->首选项->选中“在“编译”期间显示详细输出”框。

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

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

#include "foo.hh"

请注意,编译失败的文件是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 C编译器(而不是avr-gcc C ++编译器)。

然后,我打开avr-g++文件进行检查,并查找与之不同的任何内容。

接下来,我使用Eclipse开始跟踪包含项,以查看将/tmp/arduino_build_233569/sketch/foo.c插入到哪里(对我来说,问题出在哪里已经很明显了,但我还没有看到)。我发现了以下内容:

Arduino.h 可在“ Arduino / Source / Arduino / hardware / arduino / avr / cores / arduino / Arduino.h”中找到。它包括Serial。该标头"HardwareSerial.h"extern对象:

Serial

但是,回头看#if defined(UBRRH) || defined(UBRR0H) extern HardwareSerial Serial; #define HAVE_HWSERIAL0 #endif 时,您会发现Arduino.h仅在使用C ++进行编译时包括:

HardwareSerial.h

#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 意味着仅当您使用C ++编译时,才包含上述标头!就在那时候打我!您正在使用C编译器编译C文件以访问C ++对象。那不行您必须改为使用C ++编译器。只需将#ifdef __cplusplus更改为foo.c即可完成此操作。完成。

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

从Arduino IDE中找到“素描簿位置”:文件->首选项。例如,我的是foo.cpp

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

foo.cpp

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

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

在这种情况下不能使用#include <foo.h> 的原因仅仅是因为Arduino仅在以这种方式使用菜单添加库include时才在寻找foo.hh文件。 就我而言,这是一个错误,应该向Arduino开发人员报告。随时接受。

附录:

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)中,如果要包括Sketch文件夹中的库,则需要将它们放在src子文件夹中。例如:

.h

然后他说你可以这样包括:

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

我还没有尝试过,但是如果可以的话那将非常有用。试一试,让我知道它是否有效。确保告诉我们您使用的是哪个OS和Arduino IDE版本。

在此处查看有关Github的其他讨论:https://github.com/arduino/Arduino/issues/5186

答案 1 :(得分:0)

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

答案 2 :(得分:0)

  1. folder放置在libraries文件夹中,该文件夹是素描簿目录的子目录。
  2. 打开Arduino IDE(如果已经打开,请退出并重新打开)。
  3. 转到Sketch->Include Library。您将在folder部分下找到Contributed Libraries
  4. 选择folder,您一切顺利。