我已经为一个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函数设置为静态和当前所有相关的变量。之后我必须使testNTPServer函数静态并且从我只有1个错误。错误是
描述资源路径位置类型 不能调用成员函数'long unsigned int NTPlib :: sendNTPpacket(IPAddress&amp;)'没有对象NTPlib.cpp / NTP / lib行191 C / C ++问题
这个函数是它不应该需要的类的函数。当我执行此函数时,静态所有cpp都会给类的所有变量提供Undefined Reference。一个例子就是这样:
描述资源路径位置类型 更多未定义的对“NTPlib :: packetBuffer”的引用遵循NTPlib.cpp / NTP / lib行149 C / C ++问题
任何帮助?
答案 0 :(得分:0)
在C ++中,当您在类声明中声明静态数据成员时,还必须为源文件中的这些数据成员提供定义:
标题文件:
class C
{
static int MyInt;
};
源文件:
int C::MyInt = 0;