我正在尝试将一个cpp文件添加到具有以下设置的arduino项目中...
project
--folder
--foo.h
--foo.cpp
--project.ino
我在
#include "folder/foo.h
的顶部有一个project.ino
。但是,尽管 header 提供了函数的原型(prototype),但函数定义在cpp文件中。当我尝试使用Arduino IDE编译代码时,它失败并显示错误Undefined reference to 'bar()'
并且bar()
位于foo.cpp
中我查看了this,但没有
sketch/import library
的设置(但是我有sketch/include library
,但是没有看到任何类似于使用自定义文件夹位置的内容)我也看了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);
最佳答案
如何在Arduino项目中正确包含C / C++ header 和源文件。
该答案已经过测试和编译,以确保其有效。 (已在Linux Ubuntu中使用Arduino 1.8.7 IDE完成)。
您有2个问题。
第1个: Arduino的异常生成过程(described here)不允许包含项目目录中该项目的.ino
文件所在的子文件夹。
[更新:当我在PC上复制您的代码时,这个错误可能只是我的一个错误,而不是您的错误:我不小心使用了foo.c
而不是foo.cpp
]
第二个: C++只能在C++源文件中使用,因此您必须将foo.c
更改为foo.cpp
,因为Serial.println()
是C++类(Serial
的)println()
方法的C++调用。
要修复1 ,只需更改文件夹结构以将所有内容都放在一个文件夹中:
project
├── foo.cpp
├── foo.hh
└── project.ino
我也为下面的#1提供了替代解决方案。
要修复2 ,(这是强制性的!),使
foo.c
-> foo.cpp
和(可选,但建议,以显示为C++头文件)foo.h
-> foo.hh
。现在也将.ino和.cpp文件中的包含也更新为#include "foo.hh"
。而已!现在关闭Arduino IDE,然后重新打开它并重新打开您的项目,您将看到以下新选项卡:
现在可以编译了!
学习:我是怎么知道的?
首先,在Arduino IDE中打开详细编译:文件->首选项->选中“在“编译”期间显示详细输出”框。
现在,当您进行编译时,所有错误将显示在IDE窗口的底部,以及引发该错误的确切编译或链接命令。
一旦我修复了文件夹结构,但是您的文件仍然是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"
。此头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
#ifdef __cplusplus
表示仅当您使用C++编译时,才包含上述 header !就在那时候打我!您正在使用C编译器编译C文件以访问C++对象。那不行您必须改为使用C++编译器。只需将foo.c
更改为foo.cpp
即可完成此操作。做完了您的问题1(文件夹结构)的替代修补程序:
从Arduino IDE中找到“素描簿位置”:文件->首选项。例如,我的是
/home/gabriel/dev/Arduino/Sketches
。现在,去那里并创建一个“libraries”文件夹。对我来说,现在是
/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
文件。 就我而言,这是一个错误,应该向Arduino开发人员报告。 随时接受。附录:
2019年4月16日:
一个google search for "arduino add include path"使我想到了:https://forum.arduino.cc/index.php?topic=445230.0,其中@pert用户说:
In recent versions of the Arduino IDE(including 1.6.10) if you want to include libraries from the sketch folder you need to put them in a src subfolder. For example:
Blink |_Blink.ino |_src |_BlinkLib |_BlinkLib.h
然后他说您可以包括以下内容:
#include "src/BlinkLib/BlinkLib.h"
我没有尝试过,但是如果可行的话那将非常有用。试一试,让我知道它是否有效。请务必告诉我们您正在使用哪个OS和Arduino IDE版本。
在此处查看有关Github的其他讨论:https://github.com/arduino/Arduino/issues/5186。
关于c++ - 如何将cpp文件添加到arduino项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55684371/