Ant*_*ton 2 c++ arduino arduino-ide
我正在尝试将一个 cpp 文件添加到具有以下设置的 arduino 项目中...
project
--folder
--foo.h
--foo.cpp
--project.ino
Run Code Online (Sandbox Code Playgroud)
我#include "folder/foo.h
在project.ino
. 然而,虽然头文件提供了函数的原型,但函数定义在 cpp 文件中。当我尝试使用 Arduino IDE 编译代码时,它失败并显示错误
Undefined reference to 'bar()'
并bar()
位于foo.cpp
我看了这个,但我没有设置sketch/import library
(但是我有sketch/include library
,但是我没有看到任何接近使用自定义文件夹位置的东西)
我也看了这个。但与上述相同,该设置在我的 ide 中不存在。(我最近下载的)
代码
//project.ino
#include "folder/foo.h"
void setup() {
Serial.begin(9600);
}
void loop() {
bar();
}
Run Code Online (Sandbox Code Playgroud)
//folder/foo.h
#include "Arduino.h"
void bar();
Run Code Online (Sandbox Code Playgroud)
//folder/foo.cpp
#include "foo.h"
void bar() {
Serial.println("bar");
}
Run Code Online (Sandbox Code Playgroud)
错误
/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
Run Code Online (Sandbox Code Playgroud)
我期望发生的是一种链接 cpp 文件夹的方法,而不必将所有文件放在项目的同一个根文件夹中。
--编辑1:添加代码
--编辑2:添加 #include "Arduino.h"
--编辑3:添加 Serial.begin(9600);
这个答案已经过测试和编译,以确保它有效。(在带有 Arduino 1.8.7 IDE 的 Linux Ubuntu 中完成)。
你有2个问题。
第一: Arduino 不寻常的构建过程(在此处描述)不允许从项目目录中的子文件夹中.ino
包含此项目的文件所在的位置。
[更新:这可能只是我的错误,而不是你的,当我在我的电脑上复制你的代码时:我不小心使用foo.c
而不是foo.cpp
]
第二: C++ 只能在 C++ 源文件中使用,所以你必须更改foo.c
为foo.cpp
,因为Serial.println()
是对 C++ 类 ( Serial
's)println()
方法的 C++ 调用。
要修复 1,只需更改您的文件夹结构,将所有内容都放在一个文件夹中:
project
??? foo.cpp
??? foo.hh
??? project.ino
Run Code Online (Sandbox Code Playgroud)
我也为下面的 #1 提供了一个替代解决方案。
要修复 2,(这是强制性的!) make 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)
Run Code Online (Sandbox Code Playgroud)
请注意,它无法编译的文件是/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
Run Code Online (Sandbox Code Playgroud)
然而,回头看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
Run Code Online (Sandbox Code Playgroud)
#ifdef __cplusplus
意味着只有在使用 C++ 编译时才包含上面的头文件!就在那时它击中了我!您正在使用 C 编译器编译 C 文件以访问 C++ 对象。那不行。您必须改用 C++ 编译器。只需更改foo.c
为即可完成此操作foo.cpp
。完毕。
从 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!
Run Code Online (Sandbox Code Playgroud)
现在关闭并重新打开Arduino IDE,然后转到Sketch --> Include Library --> foo,它会自动为您添加以下行:
#include <foo.h>
Run Code Online (Sandbox Code Playgroud)
foo.hh
在这种情况下您不能使用的原因仅仅是因为 Arduino.h
仅在您添加库时才查找文件,包括以这种方式使用菜单。就我而言,这是一个错误,可能应该向 Arduino 开发人员报告。随意接受它。
2019年4月16日:
一个谷歌搜索“Arduino的附加包含路径”使我这个:https://forum.arduino.cc/index.php?topic=445230.0,其中用户@pert说:
在最新版本的 Arduino IDE(包括 1.6.10)中,如果您想包含草图文件夹中的库,您需要将它们放在 src 子文件夹中。例如:
Run Code Online (Sandbox Code Playgroud)Blink |_Blink.ino |_src |_BlinkLib |_BlinkLib.h
然后他说你可以像这样包括:
Run Code Online (Sandbox Code Playgroud)#include "src/BlinkLib/BlinkLib.h"
我还没有尝试过这个,但如果它有效,那将是非常有用的。试一试,让我知道它是否有效。请务必告诉我们您使用的是哪个操作系统和 Arduino IDE 版本。