0

さて、arduinoプログラム用のntpサーバーライブラリを作成しました.ntpライブラリで作成した関数を静的にしたいので、そのntpサーバークラスのオブジェクトを作成せずに他のクラスから呼び出すことができます。

私の問題は、クラスの関数と変数を1つずつ静的にするときに(一部の関数はクラス変数の一部を使用するため)、特定の関数を静的にし、ライブラリ全体でエラーが発生することです。ライブラリ全体が変数を理解できません。変数を解決できないというエラーが表示されます。また、変数のオブジェクトがないため、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関数を静的にし、もちろん関連するすべての変数を作成しました。その後、testNTPServer関数を静的にする必要があり、エラーは1つだけでした。エラーは

説明 リソース パスの場所 タイプは、オブジェクト NTPlib.cpp /NTP/lib 行 191 なしでメンバー関数 'long unsigned int NTPlib::sendNTPpacket(IPAddress&)' を呼び出せません C/C++ 問題

この関数は、オブジェクトを必要としないクラスの関数です。また、この関数 static all cpp を実行すると、クラスのすべての変数に未定義の参照が与えられます.1つの例は次のとおりです。

説明 リソース パスの場所 `NTPlib::packetBuffer' への未定義の参照をさらに入力します NTPlib.cpp /NTP/lib の 149 行目に続きます C/C++ 問題

何か助けはありますか?

4

1 に答える 1

0

C++ では、クラス宣言内で静的データ メンバーを宣言する場合、ソース ファイルでこれらのデータ メンバーの定義も提供する必要があります。

ヘッダー ファイル:

class C
{
    static int MyInt;
};

ソースファイル:

int C::MyInt = 0;
于 2013-02-18T14:38:18.693 に答える