我正在尝试向具有以下设置的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);
答案 0 :(得分:1)
此答案已经过测试和编译,以确保其有效。(已在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,然后重新打开它并重新打开您的项目,您将看到以下新选项卡:
现在可以编译了!
首先,在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
即可完成此操作。完成。
从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)
folder
放置在libraries
文件夹中,该文件夹是素描簿目录的子目录。Sketch->Include Library
。您将在folder
部分下找到Contributed Libraries
。folder
,您一切顺利。