2013-02-21 84 views
0

我使用eclipse製作arduino.I項目。將Wire.h包含到一個新類中,並且在arduinocore庫項目中,我在Wire.h頭文件中出現錯誤。誤差是在該行 76在其端部:wire.h外部雙線對象錯誤

extern TwoWire Wire; 

,它說

描述資源路徑位置類型 類型「兩線」必須實現繼承純虛方法「打印:: write'Wire.h/ArduinoCore/src line 76代碼分析問題

我給你.cpp和頭文件,它們和arduino ide裏面一樣。 我能做些什麼來解決這個問題?

#ifndef TwoWire_h 
#define TwoWire_h 



#include <inttypes.h> 
    #include "Stream.h" 

    #define BUFFER_LENGTH 32 

    class TwoWire : public Stream 
    { 
     private: 
     static uint8_t rxBuffer[]; 
     static uint8_t rxBufferIndex; 
     static uint8_t rxBufferLength; 

     static uint8_t txAddress; 
     static uint8_t txBuffer[]; 
     static uint8_t txBufferIndex; 
     static uint8_t txBufferLength; 

     static uint8_t transmitting; 
     static void (*user_onRequest)(void); 
     static void (*user_onReceive)(int); 
     static void onRequestService(void); 
     static void onReceiveService(uint8_t*, int); 
     public: 
     TwoWire(); 
     void begin(); 
     void begin(uint8_t); 
     void begin(int); 
     void beginTransmission(uint8_t); 
     void beginTransmission(int); 
     uint8_t endTransmission(void); 
     uint8_t endTransmission(uint8_t); 
     uint8_t requestFrom(uint8_t, uint8_t); 
     uint8_t requestFrom(uint8_t, uint8_t, uint8_t); 
     uint8_t requestFrom(int, int); 
     uint8_t requestFrom(int, int, int); 
     virtual size_t write(uint8_t); 
     virtual size_t write(const uint8_t *, size_t); 
     virtual int available(void); 
     virtual int read(void); 
     virtual int peek(void); 
     virtual void flush(void); 
     void onReceive(void (*)(int)); 
     void onRequest(void (*)(void)); 

     inline size_t write(unsigned long n) { return write((uint8_t)n); } 
     inline size_t write(long n) { return write((uint8_t)n); } 
     inline size_t write(unsigned int n) { return write((uint8_t)n); } 
     inline size_t write(int n) { return write((uint8_t)n); } 
     using Print::write; 
    }; 

    extern TwoWire Wire; 

    #endif 

和cpp文件:

extern "C" { 
    #include <stdlib.h> 
    #include <string.h> 
    #include <inttypes.h> 
    #include "twi.h" 
} 

#include "Wire.h" 

// Initialize Class Variables ////////////////////////////////////////////////// 

uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; 
uint8_t TwoWire::rxBufferIndex = 0; 
uint8_t TwoWire::rxBufferLength = 0; 

uint8_t TwoWire::txAddress = 0; 
uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; 
uint8_t TwoWire::txBufferIndex = 0; 
uint8_t TwoWire::txBufferLength = 0; 

uint8_t TwoWire::transmitting = 0; 
void (*TwoWire::user_onRequest)(void); 
void (*TwoWire::user_onReceive)(int); 

// Constructors //////////////////////////////////////////////////////////////// 

TwoWire::TwoWire() 
{ 
} 

// Public Methods ////////////////////////////////////////////////////////////// 

void TwoWire::begin(void) 
{ 
    rxBufferIndex = 0; 
    rxBufferLength = 0; 

    txBufferIndex = 0; 
    txBufferLength = 0; 

    twi_init(); 
} 

void TwoWire::begin(uint8_t address) 
{ 
    twi_setAddress(address); 
    twi_attachSlaveTxEvent(onRequestService); 
    twi_attachSlaveRxEvent(onReceiveService); 
    begin(); 
} 

void TwoWire::begin(int address) 
{ 
    begin((uint8_t)address); 
} 

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) 
{ 
    // clamp to buffer length 
    if(quantity > BUFFER_LENGTH){ 
    quantity = BUFFER_LENGTH; 
    } 
    // perform blocking read into buffer 
    uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); 
    // set rx buffer iterator vars 
    rxBufferIndex = 0; 
    rxBufferLength = read; 

    return read; 
} 

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) 
{ 
    return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 
} 

uint8_t TwoWire::requestFrom(int address, int quantity) 
{ 
    return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 
} 

uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) 
{ 
    return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); 
} 

void TwoWire::beginTransmission(uint8_t address) 
{ 
    // indicate that we are transmitting 
    transmitting = 1; 
    // set address of targeted slave 
    txAddress = address; 
    // reset tx buffer iterator vars 
    txBufferIndex = 0; 
    txBufferLength = 0; 
} 

void TwoWire::beginTransmission(int address) 
{ 
    beginTransmission((uint8_t)address); 
} 

// 
// Originally, 'endTransmission' was an f(void) function. 
// It has been modified to take one parameter indicating 
// whether or not a STOP should be performed on the bus. 
// Calling endTransmission(false) allows a sketch to 
// perform a repeated start. 
// 
// WARNING: Nothing in the library keeps track of whether 
// the bus tenure has been properly ended with a STOP. It 
// is very possible to leave the bus in a hung state if 
// no call to endTransmission(true) is made. Some I2C 
// devices will behave oddly if they do not see a STOP. 
// 
uint8_t TwoWire::endTransmission(uint8_t sendStop) 
{ 
    // transmit buffer (blocking) 
    int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); 
    // reset tx buffer iterator vars 
    txBufferIndex = 0; 
    txBufferLength = 0; 
    // indicate that we are done transmitting 
    transmitting = 0; 
    return ret; 
} 

// This provides backwards compatibility with the original 
// definition, and expected behaviour, of endTransmission 
// 
uint8_t TwoWire::endTransmission(void) 
{ 
    return endTransmission(true); 
} 

// must be called in: 
// slave tx event callback 
// or after beginTransmission(address) 
size_t TwoWire::write(uint8_t data) 
{ 
    if(transmitting){ 
    // in master transmitter mode 
    // don't bother if buffer is full 
    if(txBufferLength >= BUFFER_LENGTH){ 
     setWriteError(); 
     return 0; 
    } 
    // put byte in tx buffer 
    txBuffer[txBufferIndex] = data; 
    ++txBufferIndex; 
    // update amount in buffer 
    txBufferLength = txBufferIndex; 
    }else{ 
    // in slave send mode 
    // reply to master 
    twi_transmit(&data, 1); 
    } 
    return 1; 
} 

// must be called in: 
// slave tx event callback 
// or after beginTransmission(address) 
size_t TwoWire::write(const uint8_t *data, size_t quantity) 
{ 
    if(transmitting){ 
    // in master transmitter mode 
    for(size_t i = 0; i < quantity; ++i){ 
     write(data[i]); 
    } 
    }else{ 
    // in slave send mode 
    // reply to master 
    twi_transmit(data, quantity); 
    } 
    return quantity; 
} 

// must be called in: 
// slave rx event callback 
// or after requestFrom(address, numBytes) 
int TwoWire::available(void) 
{ 
    return rxBufferLength - rxBufferIndex; 
} 

// must be called in: 
// slave rx event callback 
// or after requestFrom(address, numBytes) 
int TwoWire::read(void) 
{ 
    int value = -1; 

    // get each successive byte on each call 
    if(rxBufferIndex < rxBufferLength){ 
    value = rxBuffer[rxBufferIndex]; 
    ++rxBufferIndex; 
    } 

    return value; 
} 

// must be called in: 
// slave rx event callback 
// or after requestFrom(address, numBytes) 
int TwoWire::peek(void) 
{ 
    int value = -1; 

    if(rxBufferIndex < rxBufferLength){ 
    value = rxBuffer[rxBufferIndex]; 
    } 

    return value; 
} 

void TwoWire::flush(void) 
{ 
    // XXX: to be implemented. 
} 

// behind the scenes function that is called when data is received 
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) 
{ 
    // don't bother if user hasn't registered a callback 
    if(!user_onReceive){ 
    return; 
    } 
    // don't bother if rx buffer is in use by a master requestFrom() op 
    // i know this drops data, but it allows for slight stupidity 
    // meaning, they may not have read all the master requestFrom() data yet 
    if(rxBufferIndex < rxBufferLength){ 
    return; 
    } 
    // copy twi rx buffer into local read buffer 
    // this enables new reads to happen in parallel 
    for(uint8_t i = 0; i < numBytes; ++i){ 
    rxBuffer[i] = inBytes[i];  
    } 
    // set rx iterator vars 
    rxBufferIndex = 0; 
    rxBufferLength = numBytes; 
    // alert user program 
    user_onReceive(numBytes); 
} 

// behind the scenes function that is called when data is requested 
void TwoWire::onRequestService(void) 
{ 
    // don't bother if user hasn't registered a callback 
    if(!user_onRequest){ 
    return; 
    } 
    // reset tx buffer iterator vars 
    // !!! this will kill any pending pre-master sendTo() activity 
    txBufferIndex = 0; 
    txBufferLength = 0; 
    // alert user program 
    user_onRequest(); 
} 

// sets function called on slave write 
void TwoWire::onReceive(void (*function)(int)) 
{ 
    user_onReceive = function; 
} 

// sets function called on slave read 
void TwoWire::onRequest(void (*function)(void)) 
{ 
    user_onRequest = function; 
} 

// Preinstantiate Objects ////////////////////////////////////////////////////// 

TwoWire Wire = TwoWire(); 
+0

清楚該錯誤消息說,你所要做的,就是你的問題,你不明白它說什麼?或者你不知道如何遵循它? – PlasmaHH 2013-02-21 11:48:13

+0

我不知道如何跟着它 – kyrpav 2013-02-21 17:04:05

+0

實際上,Arduino TwoWire代碼確實實現了純虛擬Print :: write()方法,而且代碼實際上使用GNU工具鏈編譯得很好。問題在於Eclipse。看到我的回答 – Greycon 2014-02-13 22:13:17

回答

-1

純虛函數或純虛方法是需要由派生類來實現,如果類不是一個抽象虛擬函數。 http://en.wikipedia.org/wiki/Virtual_function 您必須實施繼承的純虛擬方法'Print :: write'。

+0

有一個funcion命名爲:size_t TwoWire :: write(const uint8_t * data,size_t數量)是不是足夠實施的課程它是阻止與代碼?顯然它是在我刪除的部分。另外它在eclipse上說,這覆蓋了Print ::通過流 – kyrpav 2013-02-21 12:24:32

+0

寫入Downvoted,提供的OP代碼清晰地實現了write(uint_8)方法。 – Greycon 2014-02-13 22:15:50

1

這可能對你來說有點遲,但是......我也使用Eclipse來完成我所有的Arduino開發,並且我看到了這個錯誤。因爲Eclipse針對您的項目代碼運行自己的C++代碼分析工具。 (除了G ++工具鏈之外)。即使GNU編譯器編譯代碼並生成你的庫,它仍然有困難,或者過分熱衷於發現錯誤。

查看項目屬性,C/C++常規部分和代碼分析選項卡。在語法和語義列表中,最後一個檢查被稱爲「抽象類不能被實例化」。取消選中此項可禁用檢查。然後點擊Apply。

最後,用鼠標右鍵單擊您的項目,並選擇「運行C/C++代碼觀」反對它,它會清除錯誤 - 沒有更多紅色的X

希望這有助於。

0

問題:我也有類似的問題,用驚人的NetBeans IDE中,編譯錯誤是:

C:\Arduino\libraries\Wire\Wire.h:76: error: **cannot declare variable 'Wire' to be of *abstract type* 'TwoWire'** 
C:\Arduino\libraries\Wire\Wire.h:31: note: because the following virtual functions are pure within 'TwoWire': 
c:/Arduino/hardware/arduino/cores/arduino/Print.h:48: note:  virtual size_t Print::write(uint8_t) 

由於這裏在計算器上某些人,我已經明白,在之間missmatching的情況下,虛函數原型和派生類中該函數的重寫版本,編譯器抱怨。

SOLUTION:在Print.h,在第48行,我已刪除= 0從:

  • virtual size_t write(uint8_t) = 0;
  • virtual size_t write(uint8_t);

順便說,一個建議,使用Netbeans作爲開發Arduino軟件的IDE讓事情變得複雜一些......但要感謝Arduino和Netbeans,開發大型且複雜的軟件變得很容易!

http://leepike.wordpress.com/source-code/atomled-hs/makefile/

http://playground.arduino.cc/Code/Netbeans