极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12501|回复: 4

寫庫時如把程式分拆開, 如何 include 進來?

[复制链接]
发表于 2014-4-13 14:30:55 | 显示全部楼层 |阅读模式
寫了一個簡單 OLED 12864 的庫, 本想分享出來.  
一直使用 Sublime Text 2 開發, 在最後測試時, 考慮到用家可能是用 arduino 的 IDE, 所以嘗試在 arduino IDE 上再測試一次.
結果很奇怪的, 分拆出來的部份, 都出了 " multiple definition" 的錯誤.  

我再三檢查了, 絕不可能有重複的, 甚至嘗試加入一些檢測 (#ifdef _xxx_ 再 #define _xxx_ 之類, 避免同一段程式 compile 再次 compile),
結果也是一樣.

但同樣的程式, 在 Sublime Text 2 之下, 是完全沒有問題, 可以正常 compile 並 upload 到 arduino 板上執行的.

以下是之前測試時的片段 (只少了 testMsg 一部份), 同一個程式在不同 Arduino 板 (Nano 及 UNO) 及 不同顯示晶片 (SSD1306 及 SH1106) 中執行也是沒有問題的.
但在不同的 IDE 下出現了不同的結果.



現在有點苦惱, 發出來不可能要求別人也用 Sublime Text 吧.  
雖然簡單一點, 合成一個 cpp 就可以了, 但自己也想攪清楚問題所在.

想請教一下, 在寫庫的時候, 把部份程式分拆成幾個 file, 應如何加進來?

以下是我的程式(還在後期 tuning 中, 但執行是沒問題的), 希望大神可幫幫忙, 為何在 Sublime Text 中一切正常的程式, 在 Arduino IDE 中會出問題.


有興趣的朋友可以嘗試 verify 庫中的範例 OLED12864_Tester.ino.
如果有 OLED 0.96 或 1.3 i2c 板的朋友, 可以直接執行.
原設定是 0.96 吋(SSD1306 i2c)的, 把 13 行的 OLED_1306i2c 改成 OLED_1106i2c, 即 OLED12864 myOLED(OLED_1106i2c, true); 就可以在 1.3 吋的OLED 執行了.
非 i2c 的版本還在編寫中, 正考慮用不同的 class , 還是像現在的在執行時用變數決定晶片, 另一個方式比較好.

如果沒有 OLED 板子的朋友, 也可以嘗 Sublime Text 2 及 Arduino IDE 試單獨 verify/compile , 也可以看到分別.

謝謝大家幫忙.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2014-4-13 14:56:40 | 显示全部楼层
庫可能太長了, 不易看, 做了一個完全簡化版 的 DUMMY 庫, 希望可以找出問題:

庫的 header file:
[pre lang="arduino" line="1" file="DUMMY.h"]#ifndef _DUMMY_H_
#define _DUMMY_H_

#include <avr/pgmspace.h>
#include "Arduino.h"

class DUMMY {

        public:
                DUMMY();
                void setData(uint8_t data);
                uint8_t getData();

        protected:

        private:       
                uint8_t _data;

};

#endif[/code]

主庫 DUMMY.cpp:
[pre lang="arduino" line="1" file="DUMMY.cpp"]#include <avr/pgmspace.h>
#include <DUMMY.h>
#include "DUMMY_ext.cpp"

DUMMY:UMMY()
{
        _data = 0;
}

uint8_t DUMMY::getData() {
        return _data;
}[/code]

分拆了一個 setData 的 method 出來, 在 DUMMY_ext.ccp 內
[pre lang="arduino" line="1" file="DUMMY_ext.cpp"]#include <avr/pgmspace.h>
#include <DUMMY.h>

void DUMMY::setData(uint8_t data) {
        _data = data;
}[/code]

最後是一個簡單的測試程式:
[pre lang="arduino" line="1" file="DUMMY_Tester.ino"]#include <avr/pgmspace.h>
#include "DUMMY.h"

DUMMY d;

void setup()
{
        Serial.begin(9600);
        delay(1000);
        d.setData(123);

        Serial.println(d.getData());

}

void loop()
{

}[/code]

全部源碼的檔案:


同樣地, 在sublime 內完全沒問題, 但在 Arduino IDE 中就會出現以下 error:

DUMMY\DUMMY_ext.cpp.o: In function `DUMMY::setData(unsigned char)':
E:\Arduino\_dev\libraries\DUMMY/DUMMY_ext.cpp:4: multiple definition of `DUMMY::setData(unsigned char)'
DUMMY\DUMMY.cpp.o:/DUMMY_ext.cpp:4: first defined here
e:/arduino/_arduino-1.0.5-r2/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-13 15:15:31 | 显示全部楼层
找到問題了, 原來是因為我自作聰明, 根本不用 #include 也會加進來.
只是 sublime 重複再 #include 一次不會有問題, 但在 Arduino IDE 中就會看成是兩次定義.  只是不明白為何加入 #ifndef 之檢測也不行.

基本測試 OK, 可以寫一點說明就放出來了.  只是不知大家有沒有興趣試我寫的庫.
回复 支持 反对

使用道具 举报

发表于 2014-4-13 20:54:30 | 显示全部楼层
Super169 发表于 2014-4-13 15:15
找到問題了, 原來是因為我自作聰明, 根本不用 #include 也會加進來.
只是 sublime 重複再 #include 一次不 ...

這麼好的分享,感謝還來不及呢!先謝了!
回复 支持 反对

使用道具 举报

发表于 2014-4-14 10:37:50 | 显示全部楼层
Super169 发表于 2014-4-13 15:15
找到問題了, 原來是因為我自作聰明, 根本不用 #include 也會加進來.
只是 sublime 重複再 #include 一次不 ...

这个机制确实是挺奇怪的。
在VC中是需要手动include的,在这里难道只需要包含在工程里它就自动加载了?
如果把DUMMY类拿出来另外编译成一个LIB,这样应该就可以include了吧
刚用arduino IDE可能有些思想需要改变一下了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 15:49 , Processed in 0.096287 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表