C 在编译时获取纪元时间
上下文:我正在编写一种非平凡的客户机-服务器UDP多播程序,我正在一些无线节点上部署该程序。部署的方法是我编写的一个脚本,它广播ping这些节点所在的网络,获取节点列表(基于IP地址),部署我的包,然后安装它。我注意到,有时在部署时并没有检测到所有节点,而且我正在开发的最新包也没有安装。最终,在这种情况下,运行在一个节点上的服务器可能比希望与服务器通信的客户机旧。由于服务器获取数据包,并根据数据包中的条目分配内存,因此如果结构发生变化,服务器通常会在发生故障时崩溃。作为一种解决方案,我考虑在客户端和服务器之间发送的数据包中实现版本号,这样,如果服务器/客户端读取的数据包中的版本号不相同(或者由于数据包的重新构造而成为垃圾),则会忽略该数据包,并更新日志,或者向原始发送者发送紧急数据包 因此,我试图找到在编译时获取这个“版本号”的最佳方法,它可以作为C 在编译时获取纪元时间,c,c-preprocessor,epoch,C,C Preprocessor,Epoch,上下文:我正在编写一种非平凡的客户机-服务器UDP多播程序,我正在一些无线节点上部署该程序。部署的方法是我编写的一个脚本,它广播ping这些节点所在的网络,获取节点列表(基于IP地址),部署我的包,然后安装它。我注意到,有时在部署时并没有检测到所有节点,而且我正在开发的最新包也没有安装。最终,在这种情况下,运行在一个节点上的服务器可能比希望与服务器通信的客户机旧。由于服务器获取数据包,并根据数据包中的条目分配内存,因此如果结构发生变化,服务器通常会在发生故障时崩溃。作为一种解决方案,我考虑在客户
#define
放在头中。我已经查找了\uuuu时间\uuuu
预处理器宏,但它是字符串形式的。有没有一种方法可以在编译时获取历元时间,这样我就可以将其位掩码为无符号int(如果我没有记错的话,它应该只在136年后才会滚动)
如果我不清楚,很抱歉。这取决于您的构建系统,但如果您使用的是gmake,则您需要 您可以执行以下操作:
CXX_TIME = -DBUILDTIME=$(shell python -c "import time; print( int( time.time() ) )" )
将其添加到其他编译器选项中,然后使用
代码中的宏BUILDTIME
(这假设您的路径中安装了Python。
如果没有,您可以安装它,也可以对其执行类似操作
你已经安装的工具。)这取决于你的构建系统,但是如果你使用的是gmake,你就需要 您可以执行以下操作:
CXX_TIME = -DBUILDTIME=$(shell python -c "import time; print( int( time.time() ) )" )
将其添加到其他编译器选项中,然后使用
代码中的宏BUILDTIME
(这假设您的路径中安装了Python。
如果没有,您可以安装它,也可以对其执行类似操作
一个您已经安装的工具。)您可以从
\uuuu DATE\uuu
预处理器宏获取历元
下面是getCompileTimeEpoch()
函数,该函数又依赖于另外两个简单的辅助函数返回月份号,另一个函数将月份首字母缩写切换为小写
这让我困惑,GCC开发人员是如何引入一个带有人类可读日期而不是纪元的宏的,从中可以以最大的可靠性导出关于日期的任何其他内容
如果需要将时间添加到历元中,您可以很容易地从\uuuu time\uuu
宏添加时间
我选择了这个解决方案,因为它将所有内容都保存在代码中,并且不依赖于编译器选项
char *tolowercase(char *letstr){
int l;
for(l=0;l<=strlen(letstr);l++){
if(letstr[l]>=65 && letstr[l]<=92){
letstr[l]=letstr[l]+32;
}
}
return letstr;
}
int getMonFromAbbr(char *abbr){
if (strlen(abbr) > 0)
tolowercase(abbr);
if ( strcmp(abbr, "jan") == 0 )
return 0;
if ( strcmp(abbr, "feb") == 0 )
return 1;
if ( strcmp(abbr, "mar") == 0 )
return 2;
if ( strcmp(abbr, "apr") == 0 )
return 3;
if ( strcmp(abbr, "may") == 0 )
return 4;
if ( strcmp(abbr, "jun") == 0 )
return 5;
if ( strcmp(abbr, "jul") == 0 )
return 6;
if ( strcmp(abbr, "aug") == 0 )
return 7;
if ( strcmp(abbr, "sep") == 0 )
return 8;
if ( strcmp(abbr, "oct") == 0 )
return 9;
if ( strcmp(abbr, "nov") == 0 )
return 10;
if ( strcmp(abbr, "dec") == 0 )
return 11;
return(-1);
}
// Convert from __DATE__ macro
uint64_t getCompileTimeEpoch(){
char date_macro[20]="";
strcpy(date_macro, __DATE__);
char *token;
int yea=0;
int mon=0;
int day=0;
token=strtok(date_macro, " ");
if (token != NULL){
mon=getMonFromAbbr(token);
token=strtok(NULL, " ");
if (token != NULL){
day=atoi(token);
token=strtok(NULL, " ");
if (token != NULL){
yea=atoi(token);
struct tm t;
time_t epoch_t;
t.tm_year = yea-1900; // Year - 1900
t.tm_mon = mon; // Month, where 0 = jan
t.tm_mday = day; // Day of the month
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = 0; // Is DST on? 1 = yes, 0 = no, -1 = unknown
epoch_t = mktime(&t);
return epoch_t;
}
}
}
return(-1);
}
char*tolowercase(char*letstr){
int l;
对于(l=0;l=65&&letstr[l]0)
tolowercase(缩写);
if(strcmp(缩写为“jan”)==0)
返回0;
if(strcmp(缩写为“feb”)==0)
返回1;
if(strcmp(缩写为“mar”)==0)
返回2;
如果(strcmp(缩写,“apr”)==0)
返回3;
如果(strcmp(缩写,“may”)==0)
返回4;
if(strcmp(缩写,jun))=0
返回5;
if(strcmp(缩写,“jul”)==0)
返回6;
如果(strcmp(缩写为“aug”)==0)
返回7;
如果(strcmp(缩写,“sep”)==0)
返回8;
如果(strcmp(缩写,“oct”)==0)
返回9;
if(strcmp(缩写,“nov”)==0)
返回10;
如果(strcmp(缩写,“dec”)==0)
返回11;
返回(-1);
}
//从_日期_宏转换
uint64_t GetCompileTimePoch(){
字符日期_宏[20]=“”;
strcpy(日期\宏,\日期\宏);
字符*令牌;
int-yea=0;
int-mon=0;
整日=0;
令牌=strtok(日期\宏“”);
if(令牌!=NULL){
mon=getMonFromAbbr(令牌);
令牌=strtok(空,“”);
if(令牌!=NULL){
日期=atoi(代币);
令牌=strtok(空,“”);
if(令牌!=NULL){
yea=atoi(代币);
struct-tm-t;
时间、时代;
t、 tm_year=yea-1900;//年份-1900
t、 tm_mon=mon;//月份,其中0=jan
t、 tm_mday=day;//每月的第几天
t、 tm_小时=0;
t、 tm_min=0;
t、 tm_sec=0;
t、 tm_isdst=0;//DST是否开启?1=是,0=否,-1=未知
历元t=mktime(&t);
返回时间;
}
}
}
返回(-1);
}
您可以从\uuuu DATE\uuuu
预处理器宏获取历元
下面是getCompileTimeEpoch()
函数,该函数又依赖于另外两个简单的辅助函数返回月份号,另一个函数将月份首字母缩写切换为小写
这让我困惑,GCC开发人员是如何引入一个带有人类可读日期而不是纪元的宏的,从中可以以最大的可靠性导出关于日期的任何其他内容
如果需要将时间添加到历元中,您可以很容易地从\uuuu time\uuu
宏添加时间
我选择了这个解决方案,因为它将所有内容都保存在代码中,并且不依赖于编译器选项
char *tolowercase(char *letstr){
int l;
for(l=0;l<=strlen(letstr);l++){
if(letstr[l]>=65 && letstr[l]<=92){
letstr[l]=letstr[l]+32;
}
}
return letstr;
}
int getMonFromAbbr(char *abbr){
if (strlen(abbr) > 0)
tolowercase(abbr);
if ( strcmp(abbr, "jan") == 0 )
return 0;
if ( strcmp(abbr, "feb") == 0 )
return 1;
if ( strcmp(abbr, "mar") == 0 )
return 2;
if ( strcmp(abbr, "apr") == 0 )
return 3;
if ( strcmp(abbr, "may") == 0 )
return 4;
if ( strcmp(abbr, "jun") == 0 )
return 5;
if ( strcmp(abbr, "jul") == 0 )
return 6;
if ( strcmp(abbr, "aug") == 0 )
return 7;
if ( strcmp(abbr, "sep") == 0 )
return 8;
if ( strcmp(abbr, "oct") == 0 )
return 9;
if ( strcmp(abbr, "nov") == 0 )
return 10;
if ( strcmp(abbr, "dec") == 0 )
return 11;
return(-1);
}
// Convert from __DATE__ macro
uint64_t getCompileTimeEpoch(){
char date_macro[20]="";
strcpy(date_macro, __DATE__);
char *token;
int yea=0;
int mon=0;
int day=0;
token=strtok(date_macro, " ");
if (token != NULL){
mon=getMonFromAbbr(token);
token=strtok(NULL, " ");
if (token != NULL){
day=atoi(token);
token=strtok(NULL, " ");
if (token != NULL){
yea=atoi(token);
struct tm t;
time_t epoch_t;
t.tm_year = yea-1900; // Year - 1900
t.tm_mon = mon; // Month, where 0 = jan
t.tm_mday = day; // Day of the month
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = 0; // Is DST on? 1 = yes, 0 = no, -1 = unknown
epoch_t = mktime(&t);
return epoch_t;
}
}
}
return(-1);
}
char*tolowercase(char*letstr){
int l;
对于(l=0;l=65&&letstr[l]0)
tolowercase(缩写);
if(strcmp(缩写为“jan”)==0)
返回0;
if(strcmp(缩写为“feb”)==0)
返回1;
if(strcmp(缩写为“mar”)==0)
返回2;
如果(strcmp(缩写,“apr”)==0)
返回3;
如果