QT C++ 识别当前操作系统平台,并编译相应代码

需求 需要在 Qt 中检测当前的操作系统平台具体是 win 还是 linux,然后根据不同的平台执行不同的代码。比如在 linux 平台可以使用 syslog 解决 #ifdef Q_OS_LINUX #include <syslog.h> #endif #ifdef Q_OS_WIN #endif #ifdef Q_OS_OSX #endif #ifdef Q_OS_LINUX openlog(NULL, LOG_CONS | LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_LOCAL0); setlogmask(LOG_UPTO(LOG_MASK_BUILD)); #endif syslog(LOG_DEBUG, "%s: %d: %s --> class construct", __FILE__, __LINE__, __FUNCTION__); 参考 Qt判断当前系统 QT C++识别当前操作系统

2023-02-14 · 1 min · 49 words · RamLife

系统日志 syslog 相关函数使用

需求 需要让 linux 平台的软件能够输出日志,便于后期的调试和分析。 解决 linux 平台原生支持 syslog 类型的日志服务,不同的发行版可能不同,有可能是 syslog, syslog-ng, rsyslogd 等等。但是具体的程序中输出日志的函数其实是一样的,主要就是三个函数 openlog(), syslog(), closelog(). 调用 syslog 函数之前,首先需要包含相应的头文件 #include <syslog.h> openlog 函数原型为: void openlog(const char *ident, int option, int facility);, 作用是打开一个到系统日志记录程序的连接,实际使用时,这个函数可以省略,在调用 syslog() 时,如果没有打开,会自动打开一个。但是显式使用 openlog 可以进行更多的设定。 ident, 设置日志中的生成者的标识,正常使用 NULL 就可以了,会使用程序名进行标识。如果需要自定义一个标识,那么输入字符串即可。 option, 设置日志相关属性,简单的可以使用 openlog(NULL, LOG_CONS|LOG_PID, 0); 即可,复杂的使用 openlog(NULL, LOG_CONS | LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_LOCAL0);, 具体的含义可以 man openlog 可选配置 描述 LOG_CONS 直接写入系统控制台,如果有一个错误,同时发送到系统日志记录。 LOG_NDELAY 立即打开连接(通常,打开连接时记录的第一条消息)。 LOG_NOWAIT 不要等待子进程,因为其有可能在记录消息的时候就被创建了(GNU C库不创建子进程,所以该选项在Linux上没有影响。) LOG_ODELAY 延迟连接的打开直到syslog函数调用。(这是默认情况下,需要没被指定的情况下。) LOG_PERROR (不在SUSv3情况下)同时输出到stderr(标准错误文件)。 LOG_PID 包括每个消息的PID。 facility, 正常为 0 即可。 设置 描述 LOG_AUTH 认证系统:login、su、getty等 LOG_AUTHPRIV 同LOG_AUTH,但只登录到所选择的单个用户可读的文件中 LOG_CRON cron守护进程 LOG_DAEMON 其他系统守护进程,如routed LOG_FTP 文件传输协议:ftpd、tftpd LOG_KERN 内核产生的消息 LOG_LPR 系统打印机缓冲池:lpr、lpd LOG_MAIL 电子邮件系统 LOG_NEWS 网络新闻系统 LOG_SYSLOG 由syslogd(8)产生的内部消息 LOG_USER 随机用户进程产生的消息 LOG_UUCP UUCP子系统 LOG_LOCAL0~LOG_LOCAL7 为本地使用保留 syslog 函数原型为 void syslog(int priority, char*format,……);, 有需要输出的日志信息,就调用这个函数进行输出。...

2023-02-14 · 1 min · 142 words · RamLife

C 语言 offsetof

需求 offsetof 了解 解决 以前是直接自定义 offsetof 的宏,来获取结构体当中的成员偏移。类似于下面这样: #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) 后来才发现,原来 c 语言里面早就有这个了,直接 #include <stddef.h> 就可以使用了。 参考 C 库宏 - offsetof()

2023-02-03 · 1 min · 23 words · RamLife

printk 为什么不显示

需求 为什么在驱动调试的时候,有些 printk 没有显示? 解决 printk 打印的信息分等级,只有超过控制台级别,才能被打印出来。 include/linux/kern_levels.h #define KERN_SOH "\001" #define KERN_EMERG KERN_SOH "0" /* 紧急事件,一般是内核崩溃 */ #define KERN_ALERT KERN_SOH "1" /* 必须立即采取行动 */ #define KERN_CRIT KERN_SOH "2" /* 临界条件,比如严重的软件或硬件错误*/ #define KERN_ERR KERN_SOH "3" /* 错误状态,一般设备驱动程序中使用KERN_ERR 报告硬件错误 */ #define KERN_WARNING KERN_SOH "4" /* 警告信息,不会对系统造成严重影响 */ #define KERN_NOTICE KERN_SOH "5" /* 有必要进行提示的一些信息 */ #define KERN_INFO KERN_SOH "6" /* 提示性的信息 */ #define KERN_DEBUG KERN_SOH "7" /* 调试信息 */ 默认的日志级别在 kernel/printk.c 中。可以使用 cat 来获取当前设置的级别....

2020-01-06 · 1 min · 97 words · RamLife

C 语言中 typedef 用法

需求 学习了解 typedef 在 c 语言中的用法 解决 基本解释 typedef 为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型( int, char 等)和自定义的数据类型( struct 等)。 在编程中使用 typedef 目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。 至于 typedef 有什么微妙之处,请你接着看下面对几个问题的具体阐述。 <!–more–> typedef & 结构的问题 当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明: typedef struct tagNode { char *pItem; pNode pNext; } *pNode; 答案与分析 typedef的最简单使用 typedef long byte_4; 给已知数据类型long起个新名字,叫byte_4。 typedef与结构结合使用 typedef struct tagMyStruct { int iNum; long lLength; } MyStruct; 这语句实际上完成两个操作: 定义一个新的结构类型. 分析: tagMyStruct 称为“tag”,即“标签”,实际上是一个临时名字, struct 关键字和 tagMyStruct 一起,构成了这个结构类型,不论是否有 typedef ,这个结构都存在。 我们可以用 struct tagMyStruct varName 来定义变量,但要注意,使用 tagMyStruct varName 来定义变量是不对的,因为 struct 和 tagMyStruct 合在一起才能表示一个结构类型。 struct tagMyStruct { int iNum; long lLength; }; typedef 为这个新的结构起了一个名字,叫 MyStruct 。因此, MyStruct 实际上相当于 struct tagMyStruct ,我们可以使用 MyStruct varName 来定义变量。 typedef struct tagMyStruct MyStruct; 结构体指针 C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于 typedef 的应用。...

2010-12-01 · 2 min · 365 words · RamLife

C 语言结构体数组,函数指针实现简单的菜单选项功能

需求 需要通过 C 语言实现简单的数码管或者段码液晶屏的简单的菜单选项功能 解决 结构体申明和定义 在 .h 文件中申明: typedef struct value_channel { unsigned char dir; unsigned int ADCValue[128]; }v_c; extern v_c value[4]; 在 .c 文件中定义 v_c value[4]; 函数指针 定义一个函数指针 void ( * fp)(void); 函数功能和跳转 void fun_start_01(void); { ...... } void fun_start(void) { switch(cs) { case 01: fp=fun_start_01; break; } } 在菜单调用的地方使用 ( * fp)(); 即可调用相应的菜单项。 函数地址 函数地址也可以放在数组中来调用: typedef void( * dis_turn)(void); void dis_turn_1(void) void dis_turn_2(void) dis_turn dis[]={dis_turn_1,dis_turn_2}; main() { dis[0](); dis[1](); } 实现菜单 typedef void(*FUN_P)(void);//(int Data) typedef struct Message_Item { unsigned char cStatus; FUN_P fnProcess; }MSG_ITEM; MSG_ITEM MSGMap[]={{0x00,fun_start},{0x01,fun_normal},{0x02,fun_set0},{0x03,fun_gas},{0x04,fun_set}}; void SearchMSGMAP(void) //(unsigned char cStatus) { unsigned char n=0; for(n=0;n<UBOND(MSGMap);n++) { if(MSGMap[n]....

2010-12-01 · 1 min · 108 words · RamLife