1

背景:我正在编写一种非平凡的客户端-服务器 UDP 多播程序,我将其部署在一些无线节点上。部署的方法是我编写的一个脚本,它广播 ping 这些节点所在的网络,获取节点列表(基于 IP 地址),部署我的包并安装它。我注意到有时在部署时并未检测到所有节点,并且我正在开发的最新包没有安装。最终,在一个节点上运行的服务器可能比希望与服务器通信的客户端更老。因为服务器获取数据包,并根据该数据包中的条目分配内存,所以如果结构发生变化,服务器通常会在段错误中崩溃。作为解决方案,我

所以,我试图想出在编译时获取这个“版本号”的最佳方法,它可以作为#define. 我查找了__time__预处理器宏,但这是字符串的形式。有没有办法在编译期间获取纪元时间,以便我可以将其位掩码为无符号整数(如果我正确考虑的话,它应该只在 136 年后翻转)?

对不起,如果我不清楚。

4

2 回答 2

1

这取决于您的构建系统,但如果您使用的是 gmake,您可以执行以下操作:

CXX_TIME = -DBUILDTIME=$(shell python -c "import time; print( int( time.time() ) )" )

将此添加到您的其他编译器选项中,然后BUILDTIME在您的代码中使用该宏。

(这假设您已经在路径中安装了 Python。如果没有,您可以安装它,或者使用已安装的工具执行类似的操作。)

于 2013-08-13T18:00:26.907 回答
0

您可以从__DATE__预处理器宏中获取纪元。

在函数下方,该getCompileTimeEpoch()函数又依赖于另外两个简单的辅助函数,它们返回月份编号和另一个将月份首字母缩写词切换为小写的函数。

令我感到困惑的是, GCC开发人员如何引入了一个带有人类可读日期而不是纪元的宏,从中可以以最大的可靠性导出有关日期的任何其他内容。

__TIME__如果您需要将它添加到纪元,您可以很容易地从宏中添加时间。

我选择了这个解决方案,因为它将所有内容都保存在代码中并且不依赖于编译器选项。

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);
}
于 2020-12-11T10:33:18.763 回答