Just for Fun

给未来留点痕迹

示例代码

踩坑

最近在开发一个跨平台的 C++库时,在 Linux 平台运行非常正常,但在 Windows 下却怎么都没有预期的输出。为了简化问题,这里有一个存在同样问题的示例,可以看到示例中的代码非常简单,很显然预期输出应该是 5。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

using namespace std;

int main()
{
int a = 0;
// 赋一个非零的值
a = 5;
cout << a << endl;
return 0;
}

然而这个示例项目使用 VS 打开并编译运行后,输出结果却是 0。
VS运行输出

阅读全文 »

在Windows桌面软件开发完成并发布给用户使用后,难免会遇到崩溃问题。通过CrashDump文件来分析崩溃问题是一个行之有效的途径。我们可以在程序崩溃时在客户电脑上生成CrashDump文件并收集这些文件。但要打开并分析CrashDump文件,我们还需要产生CrashDump文件的可执行文件(后续称为PE文件,包括exedll文件)以及编译该PE文件时产生的符号文件(PDB)。比较基础的做法一般是在从客户电脑上拿到CrashDump文件和可执行文件后,再根据可执行文件的版本,编译时间等信息从构建服务器等地方找到相对应的PDB文件。这样带来的一个问题是我们需要手动做文件的匹配,由于PE文件,PDB文件和CrashDump文件三者是严格匹配的,即使是相同的代码,每次编译产生的文件都不一样,因此手动匹配稍有差错就会找不到正确的符号,导致无法分析CrashDump。为了解决这一问题,一个更好的方法是搭建一个符号服务器,在符号服务器上保存每次自动构建出的PE文件和PDB文件,让调试器根据CrashDump文件自动识别和匹配。下面将会介绍如何搭建一个私有的符号服务器。

阅读全文 »

在项目开发中,随着产品的更新迭代,项目会变得越来越大。项目的增大就会导致编译速度也会变得越来越慢。本人负责的一个项目的代码量如下

1
2
3
4
5
6
7
8
9
10
github.com/AlDanial/cloc v 1.80  T=0.07 s (2139.2 files/s, 210543.4 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 73 1560 453 7993
C/C++ Header 78 1167 865 2919
Markdown 1 1 0 2
-------------------------------------------------------------------------------
SUM: 152 2728 1318 10914
-------------------------------------------------------------------------------

在不同的环境下全新构建一次耗费时间(单位:秒)如下

Qt Creator Visual Studio 2017 命令行
本地 81 241 246
服务器 - - 183
阅读全文 »

本节示例代码

在Web前端开发中,有一个很重要的部分是CSS,用于修饰Html中的控件,如按钮,输入框等元素。CSS的出现分离了交互逻辑和视觉效果的开发,极大地方便了前端开发。因此这套设计理念被很多其他前端开发框架所借鉴,如Qt,Gtk,JavaFX等。在Qt中,默认的控件样式是平台相关的原始风格,很多时候难以满足视觉设计的要求,因此我们可以借助Qt中的CSSQt Style Sheet(一般简称为QSS)来对控件进行修饰美化,定制化出我们想要的效果。

阅读全文 »

本节示例代码

相信大家在初学C/C++等编程语言时,编写的都是在命令行下运行的程序,也就是运行时只用一个黑框的应用程序。和我们日常使用的GUI程序相比,这些程序除了没有一个GUI界面外,还有一个很大的区别在于这些程序是一种过程式的执行方式,执行完一行代码后再去执行下一句,执行完一个函数再去执行下一个,执行完之后程序就退出了,类似于一个批处理或脚本程序,而GUI程序是可以根据内部或外部的输入来确定执行哪些代码,以什么样的顺序去执行。这些输入可能是系统的分辨率进行了修改,或者是用户点击了一个按钮,按下了键盘上的某个键,触发了一个定时器等等。程序具体如何运行,是受到这些输入控制的,如果没有任何输入,程序将不执行任何代码。这就是批处理程序设计(batch programming)和事件驱动程序设计(Event-driven programming)的一个显著差异。

在事件驱动程序设计中,事件是核心要素,一个事件就是一个来自外界的信息输入。接触过Windows编程的人应该会了解过Windows的消息循环机制,这里的消息就类似于事件。Windows程序在收到系统派发的消息后,可以根据消息类型及消息参数的不同,进行不同的处理。例如当我们按下键盘上的Alt + F4快捷键后,Windows就会向当前的活动窗口发送一个类型为WM_CLOSE的消息,这个消息一般用于通过窗口进行关闭。窗口在收到这个消息后,原则上需要将自己关闭,但也可以选择忽略这个消息,这样我们的快捷键就“失效”了。

阅读全文 »

本节示例代码

C/C++一直为人诟病的一点就是内存管理,C/C++提供了直接的内存操作接口给用户,这虽然效率上的优势,但也带来了内存泄漏等问题。虽然C++中引入了智能指针,但这对于管理一个GUI程序来说,一个控件中可能包含多个子控件,子控件也可能包含多个子控件,控件上可能还包含一些不可见对象,当一个控件被删除后,附在其上的子控件和不可见对象也需要一并删除,智能指针也难以实现这样的效果。因此Qt引入了对象树系统。

阅读全文 »

示例代码

What

Qt提供了很多机制,其中的一个核心机制就是信号槽,信号槽在Qt程序中有着广泛的使用,是Qt有别于其他框架的一个显著特点。信号槽实际上是一种对象间通信的技术,内部使用了观察者模式。

Why

Qt的信号槽主要是为了解决对象间的通信问题。在不使用信号槽时,对象间的通信一般有两种方式,一种是A对象保持B对象的实例,然后在需要的时候调用B对象的方法,另一种是将B对象的方法作为回调函数传入A对象,在合适的时间调用。但前一种方式建立了两个对象间的强耦合关系,而后一种则使用起来比较麻烦,且可能有类型安全问题。Qt的信号槽最突出的作用就是解耦了两个对象。信号所在对象无需关注槽所在对象的信息,反之亦然。同时,Qt信号槽还提供了线程安全性,可以跨线程使用。

阅读全文 »

示例代码

Qt提供了相当多的工具方便我们进行开发,但其中有部分工具不便于单独讲解,因此本文将通过实现一个简单的播放器来介绍如何使用这些工具。本文将通过两种途径来完成软件的开发,一种使用Qt的图形化(GUI)工具来完成,另一种主要使用命令行(CLI)工具,两种途径不是绝对独立的,完全可以在不同的步骤中使用命令行或图形化工具,这需要看个人的使用习惯。由于本文重点是让大家对Qt的工具在开发过程中的作用有一个初步了解,因此每一步的具体细节将不会展开,大家可以查阅相关文档深入了解。

我们要实现的播放器主要功能是打开并播放选择的视频文件,并提供暂停和停止播放功能,程序的效果如下图所示
播放器效果图
为了实现这个播放器,我们将使用到一个第三方库VLC-Qt,这个库可以用来播放多种视频格式,性能优秀,相对于Qt自带的QMultiMedia模块要强大很多。这个库需要手动编译,我们可以参考官方文档进行编译,Windows和Macos下我们也可以直接下载已编译好的动态库,这里不再赘述。

阅读全文 »

简介

和cmake类似,qmake也是一个跨平台的构建工具,目前主要用于Qt项目的构建。本文主要基于官方文档和个人的经验做了一些介绍,更加详细的内容可以参考官方手册.

相对于其他的构建工具,qmake有一些特性:

  • 跨平台支持。为了满足Qt的跨平台性,qmake也支持运行在目前绝大部分操作系统,如Windows,Linux和MacOS,Android等。
  • 支持生成主流IDE的工程文件。qmake可以生成Visual StudioXcode的工程项目文件,便于使用IDE提供的工具。
  • 对Qt项目的完美支持。对于Qt项目,qmake可以帮我们自动配置相关编译流程,如MOC预处理,库的链接等。
  • Qt Creator提供了对qmake的良好支持。如果我们使用Qt Creator + qmake来构建一个项目,我们几乎不需要手动去修改qmake的配置文件,Qt Creator可以自动帮我们配置。

目前我们的Qt项目都是使用qmake进行构建管理,而库相关的项目主要使用cmake进行构建管理。执行qmake命令后,qmake会寻找制定路径下的pro文件并生成对应平台的makefile文件,然后我们就可以使用该平台的make工具进行编译。

阅读全文 »

Vim一个最突出的特点就是它强大的可定制性。但过度的自由也为初学者带来了一大困扰,配置太多太杂,网上的各种配置文章良莠不齐,从茫茫的配置项中找出适合自己的配置方案,完全不知道如何下手。
由于不同人有不同的习惯,因此并没有一套通用的适合所有人的配置方案,这里我仅以我常用的通用配置(2018/08/06)为例进行一个讲解。
Vim的通用配置指的是不依赖插件的一些配置,这些配置一般可被IDE等的Vim插件所支持,因此我称之为通用配置。Vim的通用配置主要分为选项,快捷键和自动命令三部分。

阅读全文 »
0%