簡體   English   中英

如何將 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 提供了 function 的原型,但 function 定義在 cpp 文件中。當我嘗試使用 Arduino IDE 編譯代碼時,它失敗並出現錯誤Undefined reference to 'bar()' and bar() is located in foo.cpp

我查看了這個但是我沒有sketch/import library的設置(但是我有sketch/include library ,但是我沒有看到任何接近使用自定義文件夾位置的東西)

我也看了這個 但是和上面一樣,我的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

我希望發生的是一種鏈接 cpp 文件夾的方法,而不必將所有文件放在項目的同一根文件夾中。

--編輯 1:添加代碼

--編輯 2: 添加#include "Arduino.h"

--編輯 3:添加Serial.begin(9600);

如何在您的 Arduino 項目中正確包含 C/C++ 標頭和源文件。

這個答案已經過測試和編譯以確保它有效。 (在帶有 Arduino 1.8.7 IDE 的 Linux Ubuntu 中完成)。

你有兩個問題。

第一: Arduino 不尋常的構建過程(在此處描述)不允許從您的項目目錄中的子文件夾中包含該項目的.ino文件所在的位置。

[更新:這可能只是我的錯誤,不是你的,當我在我的電腦上復制你的代碼時:我不小心使用了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" 此標頭externSerial對象:

#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意味着上面的標頭僅在您使用 C++ 編譯時包含。 就在那時它擊中了我。 您正在使用 C 編譯器編譯 C 文件以訪問 C++ 對象。 那不行。 您必須改用 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 日:
谷歌搜索“arduino add include path”讓我找到了這個: https ://forum.arduino.cc/index.php?topic=445230.0,用戶@pert說:

在最新版本的 Arduino IDE(包括 1.6.10)中,如果你想從 sketch 文件夾中包含庫,你需要將它們放在 src 子文件夾中。 例如:

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

然后他說你可以像這樣包括:

 #include "src/BlinkLib/BlinkLib.h"

我沒試過這個,但如果它有效,那將非常有用。 試一試,讓我知道它是否有效。 請務必告訴我們您使用的操作系統和 Arduino IDE 版本。

也可以看看:

  1. 此處關於 Github 的其他討論: https ://github.com/arduino/Arduino/issues/5186。
  2. 官方 Arduino 庫規范在這里: https ://arduino.github.io/arduino-cli/latest/library-specification/。

在項目中為每個文件打開一個選項卡。 您可以創建一個新文件或將現有文件導入到您的項目中。 這樣您就可以使用多個*.ino*.c*.cpp*.h文件。 我沒有找到導入本地目錄或配置項目結構的方法。

  1. 將您的folder放在libraries文件夾中,該文件夾是您的 sketchbook 目錄的子目錄。
  2. 打開 Arduino IDE(如果它已經打開,退出並重新打開)。
  3. 轉到Sketch->Include Library 您將在“ Contributed Libraries ”部分下找到folder
  4. 選擇folder ,一切順利。

根據“草圖規范”

 In Arduino IDE 1.6.5-r5 and older, no recursive compilation was done. In Arduino IDE 1.6.6 - 1.6.9, recursive compilation was done of all subfolders of the sketch folder. In Arduino IDE 1.6.10 and newer, recursive compilation is limited to the src subfolder of the sketch folder.

因此,將您的源代碼文件放入“src”子文件夾應該可以解決問題。 在“Arduino IDE”v2.0.3 中測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM