0、背景
界面线程由Qt实现,底层数据处理主要由C语言实现,此时C和Qt的数据交互不可避免。
1.1、Qt信号与槽
使用信号与槽的机制进行C与Qt的多线程通信。
1、定义一个用于发射信号的类SysCourier,并创建其对象sysCourier;
2、把该对象a与Qt的界面对象使用connect连接相应的信号与槽
3、在cpp文件中,定义全局函数,该全局函数调用对象a的函数发射信号
4、在头文件中使用extern “C” 的方法声明创建的全局函数。
( 该法相对直接读取全局变量、函数较为繁琐,但避免了多线程造成的数据混乱,且在某些时候具有更好的优势,下面将讲述 )
例子如下:
类SysCourier头文件SysCourier.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<span style="font-size:14px;">#ifndef SYSCOURIER_H #define SYSCOURIER_H #include <QObject> class SysCourier : public QObject { Q_OBJECT public: explicit SysCourier(QObject *parent = 0); /* CPP文件的全局函数通过sysCourier调用此函数,发射信号 sg_updateInfo(int arg, const char * msg); */ void comUpdateInfo(int arg, const char * msg); signals: void sg_updateInfo(int arg, const char * msg); }; extern SysCourier *sysCourier; //声明通信类对象的指针,让包含该头文件的CPP文件可访问该对象 #endif // SYSCOURIER_H</span>
类SysCourier源文件SysCourier.cpp
1
2
3
4
5
6
7
8
9
10<span style="font-size:14px;">#include "syscourier.h" SysCourier::SysCourier(QObject *parent) : QObject(parent) { } void SysCourier::comUpdateInfo(int arg, const char * msg) { Q_EMIT(sg_updateInfo(arg, msg)); }</span>
供C语言文件调用的C++函数接口,头文件 c2qt.h
1
2
3
4<span style="font-size:14px;">#ifndef COMBYQT_H #define COMBYQT_H #ifdef __cplusplus //使用该宏,使该文件按c的方式去编译,这样c文件就可
1
2
3
4
5
6
7
8extern "C" //调用此文件描述的函数声明 { #endif extern void update_sys_startinfo(int arg, const char *msg); #ifdef __cplusplus } #endif #endif // COMBYQT_H</span>
对应的源文件 c2qt.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13<span style="font-size:14px;">#include <QSettings> #include <QDebug> #include "c2qt.h" extern "C" { static char buf[64];//定义一个静态内存区,存放临时通信数据,防止传入的指针未被Qt使用就在C语言的线程中释放 void update_sys_startinfo(int arg, const char *msg) { strcpy(buf, msg);//数据存入临时内存区 //发射信号 sysCourier->comUpdateStartInfo(arg, buf); } }</span>
1.2、Qt事件机制
略
1.3、直接使用全局变量、全局函数
1)、Qt引用C的全局变量、函数:直接引用即可
2)、C引用Qt的全局变量、函数,需使用extern “C”的宏编译方法
1.4、方法对比
对于上述通信办法,应根据业务需求作出合适的选择。我认为可以分为两种类型:
1)、被动需求:(被需要)
如:底层某个状态变量发生变化时,需在界面中体现出来,Qt可以通过定时器或循环阻塞轮询读取该状态变量是否发生变化,但此法消耗量大,反应亦不一定迅速,故性价比低。此时即可使用Qt信号与槽的机制或事件机制。
2)、主动需求:
如:底层线程在运行过程需要获取界面某个变量或结构,最简单的办法是直接读取该值(该结构定义为全局或通过全局函数返回该结构),同理,界面线程在运行过程需要用到某个结构值时,也可直接读取。
最后
以上就是拼搏哈密瓜最近收集整理的关于Qt与C语言交互探讨的全部内容,更多相关Qt与C语言交互探讨内容请搜索靠谱客的其他文章。
发表评论 取消回复