2013-02-18 75 views
0

嗯,我做了一個arduino程序的ntp服務器庫。我想讓我在ntp lib中創建的函數是靜態的,所以我可以從其他類調用它們而不用創建該ntp服務器類的對象。靜態函數

我的問題是,當我逐個製作靜態類函數和變量(因爲一些函數使用了一些類變量),我發現自己製作了一個靜態的函數,然後整個函數庫出錯。整個庫不能理解任何變量。我得到錯誤,變量不能解決我也得到錯誤,NTP類的功能不能打賭使用,因爲沒有對象爲他們(但它是類的功能和那裏沒有實施到另一個班級)。 我會給你我的代碼。

#ifndef NTPLIB_H_ 
#define NTPLIB_H_ 

#include "Arduino.h" 
#include "SPI.h" 
#include "IPAddress.h" 
#include "EthernetUdp.h" 
#include "Ethernet.h" 
#include "DayNumber.h" 

class NTPlib { 

private: 


public: 
    static EthernetUDP Udp; 
    static DayNumber DN; 


    static const int Gmt=2; 
    static const unsigned int localPort = 8888; 
    static const int NTP_PACKET_SIZE=48; 

    static byte packetBuffer[NTP_PACKET_SIZE ]; 

    unsigned long secsSince1900; 
    unsigned long UnixTime; 
    static unsigned long daysPassedInYear; 
    static int utchour; 
    static int lcthour; 
    static int min; 
    static int sec; 
    static int year; 
    static int month; 
    static int date; 
    static int dayOfWeek; 



    NTPlib(); 
    static NTPlib getTime(); 
    static bool testNtpServer(); 
    void startEthernetAndUdp(); 
    unsigned long static sendNTPpacket(IPAddress& address); 

    virtual ~NTPlib(); 
}; 

#endif /* NTPLIB_H_ */ 

這是頭文件,這裏是.cpp文件

#include "NTPlib.h" 


NTPlib::NTPlib() { 
    // TODO Auto-generated constructor stub 

} 

NTPlib NTPlib::getTime(){ 

    if (testNtpServer()){ 
     // We've received a packet, read the data from it 
     Udp.read((unsigned char*)packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer 

     //the timestamp starts at byte 40 of the received packet and is four bytes, 
     // or two words, long. First, extract the two words: 
     unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); 
     unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 

    // combine the four bytes (two words) into a long integer 
     // this is NTP time (seconds since Jan 1 1900): 
     unsigned long secsSince1900 = highWord << 16 | lowWord; 
     Serial.print("Seconds since Jan 1 1900 = "); 
     Serial.println(secsSince1900); 
     // now convert NTP time into everyday time: 
     // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: 
     const unsigned long seventyYears = 2208988800UL; 
     // subtract seventy years: 
     unsigned long UnixTime = secsSince1900 - seventyYears; 


     sec = UnixTime % 60; 
     //calc min 
     min = (UnixTime/60)%60; 
     //calc hour 
     utchour = (UnixTime/3600)%24; 
     lcthour = utchour + Gmt; 
     //day of the week 
     dayOfWeek = (((UnixTime/86400UL) + 3) % 7) + 1;//setting first day Sunday=1 

     // print Unix time: 
     Serial.print("Unix time = "); 
     Serial.println(UnixTime); 

     Serial.print("the day is : "); 
     Serial.println(dayOfWeek); 

     Serial.print("The LTC time is "); 
     Serial.println(lcthour); 


     unsigned long UnixTimeToDays=UnixTime/86400UL; 
     Serial.println(UnixTimeToDays); 
     unsigned long calcDaysInYears=0; 
     int calcYear=1970; 
     while((calcDaysInYears+= (DN.checkLeapYear(calcYear)? 366:365)) <= UnixTimeToDays){ 
      calcYear++; 
     } 
     //setting year 
     year = calcYear; 
     Serial.print("the year is :"); 
     Serial.println(year); 


     //calculating days in this year 
     calcDaysInYears -= (DN.checkLeapYear(calcYear)? 366:365); 
     daysPassedInYear = UnixTimeToDays - calcDaysInYears; 
     Serial.println(daysPassedInYear); 

     //set Daynumber one year loop 
     DN.Days1YearLoop = daysPassedInYear+1; 
     //calculating date and month 
     static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; 

     int calcMonth; 
     int monthLength; 

     for (calcMonth=0; calcMonth<12;calcMonth++){ 
      if (DN.checkLeapYear(year)){ 
       monthLength = (calcMonth==1) ? 29: 28; 
      }else{ 
       monthLength = monthDays[calcMonth]; 
      } 
      if (daysPassedInYear > monthLength){ 
       daysPassedInYear -= monthLength; 
      }else{ 
       break; 
      } 
     } 
     month = ++calcMonth; 
     date = ++daysPassedInYear; 
     Serial.print("Month is : "); 
     Serial.print(month); 
     Serial.print(" Date is: "); 
     Serial.println(date); 

     // print the hour, minute and second: 
     Serial.print("The UTC time is ");  // UTC is the time at Greenwich Meridian (GMT) 
     Serial.print(utchour); // print the hour (86400 equals secs per day) 
     Serial.print(':'); 

     if (min < 10) { 
     // In the first 10 minutes of each hour, we'll want a leading '0' 
      Serial.print('0'); 
     } 
     Serial.print(min); // print the minute (3600 equals secs per minute) 
     Serial.print(':'); 

     if (sec < 10) { 
     // In the first 10 seconds of each minute, we'll want a leading '0' 
      Serial.print('0'); 
     } 
     Serial.println(sec); // print the seconds 

     return NTPlib(); 

    }else{ 
    //error ntp time from DS1307 
     Serial.println("RTC"); 
     return NTPlib(); 
    } 
} 

unsigned long NTPlib::sendNTPpacket(IPAddress& address){ 

    // set all bytes in the buffer to 0  
    memset(packetBuffer, 0, NTP_PACKET_SIZE); 
    // Initialize values needed to form NTP request  
    // (see URL above for details on the packets)  
    packetBuffer[0] = 0b11100011; // LI, Version, Mode  
    packetBuffer[1] = 0;  // Stratum, or type of clock  
    packetBuffer[2] = 6;  // Polling Interval  
    packetBuffer[3] = 0xEC; // Peer Clock Precision  
    // 8 bytes of zero for Root Delay & Root Dispersion  
    packetBuffer[12] = 49;  
    packetBuffer[13] = 0x4E;  
    packetBuffer[14] = 49;  
    packetBuffer[15] = 52;  
    // all NTP fields have been given values, now 
    // you can send a packet requesting a timestamp:  
    Udp.beginPacket(address, 123); //NTP requests are to port 123  
    Udp.write(packetBuffer,NTP_PACKET_SIZE);  
    Udp.endPacket(); 

} 

void NTPlib::startEthernetAndUdp(){ 

//declaration of the mac address of ethernet shield 
    byte mac[]= {0x00,0xAA,0xBB,0xCC,0xDE,0x02}; 
    if (Ethernet.begin(mac) == 0) { 
     Serial.println("Failed to configure Ethernet using DHCP"); 
     // no point in carrying on, so do nothing forevermore: 
     //for(;;) 
     // ; 
    } 

    Udp.begin(localPort); 
} 

bool NTPlib::testNtpServer(){ 

    byte serverslist[4][4]={ 
      193,93,167,241, 
      129,215,160,240, 
      138,195,130,71, 
      132,163,4,101 
    } ; 
    IPAddress ntpServers(serverslist[0]); 
    sendNTPpacket(ntpServers); 
    int x=0; 
    delay(1000); 

    while(!Udp.parsePacket() && x<=3){ 
      x++; 
      IPAddress ntpServers(serverslist[x]); 
      Serial.println("ton pairneis"); 
      sendNTPpacket(ntpServers); 
      delay(1000); 
     } 

    if (x<=3){ 
     Serial.print("leitoyrgei o server "); 
     Serial.println(++x); 
     return true; 
    }else{ 
     return false; 
    } 
} 


NTPlib::~NTPlib() { 
    // TODO Auto-generated destructor stub 
} 

以及起初我做GETTIME功能的靜態和ofcourse所有相關variables.After,我不得不做出testNTPServer功能靜從我只有1錯誤。錯誤是

描述資源路徑位置類型 不能調用成員函數 '長無符號整型NTPlib :: sendNTPpacket(ip地址&)' 無對象NTPlib.cpp/NTP/lib中線191 C/C++問題

這個函數是它不應該需要的對象的類的一個函數。還當我做這個功能的靜態所有CPP給未定義引用的所有class.One實例變量是這樣的:

描述資源路徑位置類型 多個未定義爲'NTPlib :: packetBuffer」跟隨NTPlib引用.cpp/NTP/lib行149 C/C++問題

任何幫助?

+2

這是可以修復的,但是你最好不要*使用一個充滿靜態函數的類,而是在命名空間中放置非成員函數。對於const靜態數據也是如此。 – juanchopanza 2013-02-18 14:24:33

+0

它是如何修復的? – kyrpav 2013-02-18 14:31:53

+1

你必須*定義*靜態數據成員。到目前爲止,據我所知,你只有*宣佈*他們。 – juanchopanza 2013-02-18 14:33:57

回答

0

在C++中,當你聲明一個類聲明中的靜態數據成員,你還必須提供一個源文件的數據成員的定義:

頭文件:

class C 
{ 
    static int MyInt; 
}; 

源文件:

int C::MyInt = 0; 
+0

但爲什麼這個定義問題出現後,我使最後一個函數靜態,而不是當我做了gettime靜態,其中包含最多的變量。也內部gettime函數的變量得到初始化。另外,大部分變量都在頭文件中初始化。其中一些變量在gettime函數運行之前不應獲取值。 – kyrpav 2013-02-18 14:54:04

+0

另外,如果我這樣做「NTPlib :: sec = UnixTime%60;」在函數內部我得到相同的錯誤。那麼我不能將變量設置爲零或從頭部初始化變量呢? – kyrpav 2013-02-18 14:57:16

+0

像pucketbuffer或udp.read它不理解udp對象,它的構造函數沒有操作符。 – kyrpav 2013-02-18 15:03:45