如何将 cpp 文件添加到 arduino 项目中?
How do I add cpp file to an arduino project?
我正在尝试将 cpp 文件添加到具有以下设置的 arduino 项目...
project
--folder
--foo.h
--foo.cpp
--project.ino
我在 project.ino
的顶部有一个 #include "folder/foo.h
。然而,虽然 header provide 是函数的原型,但函数定义在 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
我希望发生的是一种 link cpp 文件夹的方法,而不必将所有文件都放在项目的同一根文件夹中。
--编辑1:
添加代码
--编辑2:
添加了 #include "Arduino.h"
--编辑3:
添加了 Serial.begin(9600);
在您的项目中为每个文件打开一个选项卡。
您可以创建一个新文件或将现有文件导入到您的项目中。
这样您就可以使用多个 *.ino
、*.c
、*.cpp
和 *.h
文件。我没有找到导入本地目录或配置项目结构的方法。
- 将您的
folder
放在 libraries
文件夹中,该文件夹是您的 sketchbook 目录的子目录。
- 打开Arduino IDE(如果已经打开,退出并重新打开)。
- 前往
Sketch->Include Library
。您会在 Contributed Libraries
部分下找到 folder
。
- 选择
folder
就可以了。
如何在您的 Arduino 项目中正确包含 C/C++ headers 和源文件。
此答案已经过测试和编译以确保其有效。(在 Linux Ubuntu 中使用 Arduino 1.8.7 IDE).
您有 2 个问题。
1st: Arduino 不寻常的构建过程 (described here) 不允许从 sub-folders 包含在您的 .ino
所在的项目目录中该项目的文件位于。
[更新:这可能只是我的错误,不是你的,当我在我的电脑上复制你的代码时:我不小心使用了 foo.c
而不是 foo.cpp
]
2nd: C++只能在C++源文件中使用,所以你必须把foo.c
改成foo.cpp
,因为Serial.println()
是C++调用a C++ class 的(Serial
的)println()
方法。
要修复 1,只需更改您的文件夹结构,将所有内容都放在一个文件夹中:
project
├── foo.cpp
├── foo.hh
└── project.ino
我也为下面的 #1 提供了替代修复方法。
修复 2,(这是强制性的!)使 foo.c
--> foo.cpp
和(可选,但推荐,以显示它是一个 C++ header 文件)foo.h
--> foo.hh
。现在也将 .ino 和 .cpp 文件中的包含更新为 #include "foo.hh"
.
就是这样!现在关闭 Arduino IDE,然后重新打开它并重新打开您的项目,您将看到以下新选项卡出现:
现在可以正常编译了!
学习:我是怎么想出来的?
首先,在 Arduino IDE 中打开详细编译:文件 --> 首选项 --> 选中“在 'compilation' 期间显示详细输出”复选框。
现在,当您编译时,所有错误都会显示在 IDE window 的底部,以及 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"
。这个 header extern
是 Serial
object:
#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
表示上面的 headers 仅在您使用 C++ 编译时包含!就在那时它击中了我!您正在使用 C 编译器编译 C 文件以访问 C++ object。那不行。您必须改用 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
文件。 就我而言,这是一个错误,可能应该向 Arduino 开发人员报告。随时接受。
附录:
2019 年 4 月 16 日:
A google search for "arduino add include path" led me to this: 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。
- 官方 Arduino 库规范在这里:https://arduino.github.io/arduino-cli/latest/library-specification/。
我正在尝试将 cpp 文件添加到具有以下设置的 arduino 项目...
project
--folder
--foo.h
--foo.cpp
--project.ino
我在 project.ino
的顶部有一个 #include "folder/foo.h
。然而,虽然 header provide 是函数的原型,但函数定义在 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
我希望发生的是一种 link cpp 文件夹的方法,而不必将所有文件都放在项目的同一根文件夹中。
--编辑1: 添加代码
--编辑2:
添加了 #include "Arduino.h"
--编辑3:
添加了 Serial.begin(9600);
在您的项目中为每个文件打开一个选项卡。
您可以创建一个新文件或将现有文件导入到您的项目中。
这样您就可以使用多个 *.ino
、*.c
、*.cpp
和 *.h
文件。我没有找到导入本地目录或配置项目结构的方法。
- 将您的
folder
放在libraries
文件夹中,该文件夹是您的 sketchbook 目录的子目录。 - 打开Arduino IDE(如果已经打开,退出并重新打开)。
- 前往
Sketch->Include Library
。您会在Contributed Libraries
部分下找到folder
。 - 选择
folder
就可以了。
如何在您的 Arduino 项目中正确包含 C/C++ headers 和源文件。
此答案已经过测试和编译以确保其有效。(在 Linux Ubuntu 中使用 Arduino 1.8.7 IDE).
您有 2 个问题。
1st: Arduino 不寻常的构建过程 (described here) 不允许从 sub-folders 包含在您的 .ino
所在的项目目录中该项目的文件位于。
[更新:这可能只是我的错误,不是你的,当我在我的电脑上复制你的代码时:我不小心使用了 foo.c
而不是 foo.cpp
]
2nd: C++只能在C++源文件中使用,所以你必须把foo.c
改成foo.cpp
,因为Serial.println()
是C++调用a C++ class 的(Serial
的)println()
方法。
要修复 1,只需更改您的文件夹结构,将所有内容都放在一个文件夹中:
project
├── foo.cpp
├── foo.hh
└── project.ino
我也为下面的 #1 提供了替代修复方法。
修复 2,(这是强制性的!)使 foo.c
--> foo.cpp
和(可选,但推荐,以显示它是一个 C++ header 文件)foo.h
--> foo.hh
。现在也将 .ino 和 .cpp 文件中的包含更新为 #include "foo.hh"
.
就是这样!现在关闭 Arduino IDE,然后重新打开它并重新打开您的项目,您将看到以下新选项卡出现:
现在可以正常编译了!
学习:我是怎么想出来的?
首先,在 Arduino IDE 中打开详细编译:文件 --> 首选项 --> 选中“在 'compilation' 期间显示详细输出”复选框。
现在,当您编译时,所有错误都会显示在 IDE window 的底部,以及 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"
。这个 header extern
是 Serial
object:
#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
表示上面的 headers 仅在您使用 C++ 编译时包含!就在那时它击中了我!您正在使用 C 编译器编译 C 文件以访问 C++ object。那不行。您必须改用 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
文件。 就我而言,这是一个错误,可能应该向 Arduino 开发人员报告。随时接受。
附录:
2019 年 4 月 16 日:
A google search for "arduino add include path" led me to this: 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。
- 官方 Arduino 库规范在这里:https://arduino.github.io/arduino-cli/latest/library-specification/。