网络寻租

Programmer, Gamer, Hacker

Qt编译加速以及使用预编译头

| Comments

方法

上次讲了如何使用预编译头来加速编译,现在给出一个Qt程序实际的例子,来演示 预编译头的好处.

我们采用qmake来编译Qt程序,qmake本身支持预编译头, 文档在这:http://doc.trolltech.com/3.3/qmake-manual-7.html

使用方法很简单,在pro文件里面加上这几行即可:

PRECOMPILED_HEADER = lib.hpp #头文件名
CONFIG += precompile_header #设置使用预编译头功能

示例

以下是我测试项目的例子. 文件目录:

halida@halida-desktop:~/temp/build-qt$ ls
build-qt.pro   lib.hpp    main.cpp   shower.cpp    shower.hpp

没有使用预编译头时消耗的时间:

halida@halida-desktop:~/temp/build-qt$ touch *.cpp
halida@halida-desktop:~/temp/build-qt$ time make>>/dev/null
real    0m7.292s
user    0m4.696s
sys     0m2.340s

使用预编译头后消耗的时间:

halida@halida-desktop:~/temp/build-qt$ touch *.cpp
halida@halida-desktop:~/temp/build-qt$ time make>>/dev/null
real    0m2.416s
user    0m1.324s
sys     0m1.004s

很明显,提升了相当多的速度.

例子可以在这里下载: http://linjunhalida.72pines.com/files/2010/09/build-qt.zip

采用libusb库让PC与USB通讯

| Comments

需求

作为设备开发者, 一般需要让设备与上位机PC通讯, 我们往往考虑采用以下几种接口: rs232, USB, ethernet.

现在在PC机上已经很难见到rs232的接口, 而ethernet也需要做特殊的配置, USB大多成为我们的首选. 对于数据偏少的应用, 我们可以利用USB虚拟串口的方式来完成这样的任务, 虚拟串口的驱动和实例, 对于下位机来说也非常常见. 有个问题: 很多应用无法用虚拟串口的方式来得到满足, 只能按照USB的方式来解决问题. 这个时候, 我们只好针对USB进行编程. 对于复杂的驱动编程, 大多数程序员往往望而却步. 不过总有其他简单的方法解决问题. 这里, 我们介绍一个USB通讯库: libusb.

介绍

libusb是一个针对usb通讯的库. 使用它, 你不需要知道操作系统的细节, 你只需要对USB有足够的了解即可. 它也不需要你写驱动, 所有的工作都可以在用户态完成. 使用方法很简单, 这里有一个示例: http://sourceforge.net/apps/trac/libusb-win32/wiki/libusbwin32_documentation#IV.Examples , 是不是很简单?

原理

libusb自己带有一个内核驱动, 名字叫libusb0.sys, 放在WINDOWSSYSTEM32DRIVERS里面. 用户程序调用libusb0.dll, dll会把任务交由驱动来完成. 这样保证用户态就能够完成USB通讯的作业.

具体做了什么, 可以通过下载项目的源文件来了解, 等我有时间的时候再看看吧.

安装方法

libusb现在有好几个版本. 主页面在这里: http://www.libusb.org/

  • 因为我们一般是进行工程应用, 选择相对稳定的版本: libusb-0.1.
  • 平台在windows下的话, 我们采用libusb-win32: http://www.libusb.org/wiki/libusb-win32
  • linux下一般已经添加到源里面去了, 查找libusb即可.

windows下安装方法: http://www.libusb.org/wiki/libusb-win32#Installation

里面有2种安装方式, Filter Driver Installation 和 Device Driver Installation, 前面一个可以说是开发环境, 后面可以说是发布驱动本身. 我们因为是做系统, 选择前面一个方式, 省得麻烦.

使用

这里有比较详细的文档: http://sourceforge.net/apps/trac/libusb-win32/wiki/libusbwin32_documentation

Sqlalchemy学习

| Comments

什么是sqlalchemy

sqlalchemy是python下面一个专门用来处理sql问题的工具包.

纵览

  • python里面处理数据库的工具
  • 模块区分

image

如何使用预编译头以及预编译头的原理

| Comments

问题

在c/c++里面,如果一个xxx.c要暴露出接口给其他文件的话,一般是提供一个xxx.h的文件作为接口,然后其他文件会把xxx.h文件包含进自己里面去,这样就可以知道xxx.c提供了什么.

但是会出现这样的问题,如果一个xxx.h文件被包含了N次,那么项目在编译的时候,会把这部分的代码重复编译N次,当这个xxx.h文件非常大的时候,编译速度就很慢了.比如xxx.h代表了一个库.(Qt, windows等)

解法

为了解决这个问题,我们可以先把头文件编译好,然后再包含到其他文件里面去.这样,每个引用了该头文件的源文件就不需要再次编译这部分了.

示例

来自: http://stackoverflow.com/questions/58841/precompiled-headers-with-gcc

建立以下文件:

stdafx.h:

1
2
#include <string>
#include <stdio.h>

a.cpp:

1
2
3
4
5
6
#include "stdafx.h"
int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

编译和执行命令:

g++ -c stdafx.h -o stdafx.h.gch
g++ a.cpp
./a.out

删除了stdafx.h文件之后,执行g++ a.cpp照样编译成功.

实现的原理很简单:

  • 首先把一个stdafx.h头文件,编译成stdafx.h.gch.
  • 当执行g++ a.cpp的时候,g++编译器会先去找stdafx.h.gch, 把它包含进来.这样就节省了编译时间.

如果stdafx.h被很多源文件引用,节省的编译时间是很可观的.

结论

利用预编译头文件,可以很明显地感觉到编译速度的提升.建议大家尝试一下.

还有一个有点相关的问题,如果修改了一个用到很多的头文件,就需要把所有用到这个头文件的源文件编译一遍,基本上等于重新编译了.所以,尽量少修改这种头文件.

Docstring

| Comments

注意事项

  • 为了统一,docstring的注释用 """ """
  • 不要硬性说返回什么,因为无法确定.要表示会返回什么.
  • class的docstring要与上下分离开来,表示单独的一个部分.
  • override重载和extend扩展要注明
  • fill-paragraph断行

实例

1
2
3
4
5
6
7
8
9
10
11
def kos\_root():
  ~ """Return the pathname of the KOS root directory.""" global
    \_kos\_root if \_kos\_root: return \_kos\_root ...

def complex(real=0.0, imag=0.0):
  ~ """Form a complex number.

    Keyword arguments: real -- the real part (default 0.0) imag -- the
    imaginary part (default 0.0)

    """ if imag == 0.0 and real == 0.0: return complex\_zero ...

实现计算器

| Comments

原因

因为想要练习自己的编程能力, 所以打算写一个计算器出来.

具体的需求: – 实现一个支持四则运算的计算器 – 实现括号, 乘方运算

分析

我打算的实现步骤如下: – 实现词法解析器, 把输入的字符串解析成词语. – 实现简单的四则运算语法分析与计算

词法解析器

采用状态机来实现

词法:

number := [0..9] | number [0..9]
add := +
sub := -
mul := *
div := /
lp  := (
rp  := )
mmu := **

根据词法获得的状态表格:

----------------- -------- --------- ------- -----
statuscondition   [0..9]   [+-/()]   [\*]    [ ]
0.start           1 num    0 fac     2       0
1.numcheck        1 num    0 fac     0       0
2.mulcheck        1 num    0 fac     0 mmu   0
----------------- -------- --------- ------- -----

当跳出number状态时, 记录number. 当跳出mulcheck状态时, 记录mul.

四则运算语法分析和处理

先来一个简单的吧, 只实现四则运算, 2次循环, 一次计算*/, 一次计算+–, 然后打印出结果.

实现完成, 函数是caculate.

然后是能够实现括号, 乘方等复杂操作, 这个需要语法分析, 甚至可能用到AST(抽象语法树)

语法

prime := ( p3 ) | number
p1 := prime ** prime | prime
p2 :=  p2 * p1 | p2 / p1 | p1
p3 := p3 - p2 | p3 + p2 | p2

自己研究了半天, 最后还是看the c programming language里面的解法完成了.

总共花费了1天, 看起来过了一个有意义的中秋(好悲哀).

CortexCommand介绍

| Comments

介绍

Cortex Command是一个2D的平面射击,基地建设等概念的独立游戏, 官方网站 上面有介绍和下载.

我现在已经花了至少一周的时间,在玩这个游戏上面,而这个游戏甚至还没有完成!

一些游戏中的画面:

image image

为什么这个游戏很好玩?

最主要的有几点:

  • 激烈的热武器战斗。
  • 基地建设。
  • 非常丰富的MOD(非官方出的扩展模块)
  • 自由定制。游戏除了可执行文件文件以外,所有的资源和游戏脚本,都可以自己编辑。

恩,其实网络上面有非常多的 视频 可以看到这个游戏的效果, 非常劲爆.

如何获取游戏?

在官方网站上面有免费版下载,地址在 这里.

如果你不在乎版权问题的话,你可以在幻想游戏网站上面下载 破解版.

如果你觉得官方版本太简陋的话, 你可以下载许多的模组, 包括辐射,战锤,毁灭公爵,以及各种各样奇奇怪怪的东西. 当然还有非常多的地图可以下载. 这些都可以在 官方论坛 里面找到.

Unix的哲學

| Comments

以前看過UNIX編程藝術一書,里面提到了unix的哲學,以及對應能夠帶來的好處:

問題分解為子問題:

好處在于解決方案可重用,針對單一問題的解決方案可以得到改進的機會。

統一接口(文本方式,采用輸入流,輸出流,錯誤流),UNIX強大的管道功能:

好處在于使得多程序間通信成為可能,人也能在這個過程中觀察程序的運作方式。

開放源碼:

邀請用戶參與改進源代碼,以程序提升為目標,使得程序能夠傳世。

可配置,可自動化:

程序的配置可以通過寫配置文檔和調節參數來完成,而程序執行也可以完全交由計算機來做,完全解放了電腦使用人員的人力。

雖然有些點在實際的應用中會有些限制(因為市場,政治,成本等原因),但是這些精神可以指導我們在軟件,甚至生活方式上面得到進步。

音乐为什么能够感染人

| Comments

音乐为什么会激发人的情绪?

音乐有什么?特殊的调子,稳定的节奏。

节奏调控肉体,方便整体协调一致。

特殊的调子,则传递出信息,控制人们的情绪。

无论是战争,还是劳动,音乐都是人的好帮手。

可是现在为什么不允许上班的时候听音乐呢?

一边听音乐一边coding效率很高的。

從信息的角度來看待軟件開發

| Comments

個人感覺,程序開發,是一個處理信息的過程。 一開始,我們什么都不知道,需求也是模糊的。 在需求分析過程中,我們漸漸能夠看清到底需要完成什么功能。 但是如何實現這樣的功能,我們還是不了解。 在設計階段,我們根據需求的內容,嘗試一個個原型,直至找到合適的,或者根據需求

創造出一個。 事實上,需求的信息量如此之大,可能有很多的原型,才有可能覆蓋住需求的要求。 之后是裁剪,組合,分割,把需求的信息量,整理成原型的模樣, 需求的信息處理得清清楚楚,整整齊齊。 最后還要看看有沒有信息遺漏的。 之后是寫代碼和寫文檔,確保這個過程中,信息沒有變化。

實際中,信息流不是那么清晰的,會有一些正反饋和負反饋, 信息在傳遞的過程中還會有失真和遺漏,于是傳遞系統就有了冗余和校驗。

一個新視角,可以帶來新的理論和方法,比如用信息處理的方法來指導軟件的設計和開發。 我想,應該有人在這方面做過研究的。