0%

thunk是什么?查字典只能让人一头雾水。thunk是一段插入程序中实现特定功能的二进制代码,这个定义是我下的,对不对各位看官请自己斟酌,呵呵。

我这里要讲的是窗口回调专用thunk,thunk的核心是调用栈动态修改技术。地球人都知道,windows的窗口回调函数是一个全局函数,类成员函数 是不可以作为窗口回调函数的,因为它有this指针,这给我们用C++来包装窗口带来不小的麻烦。你说什么?用一个全局函数或类的静态成员函数来做窗口回 调函数?这肯定没问题。但是这样带来的麻烦也许比你想象的要多,想想我们的GUI Framework不会只有一个类,而是一个类层级结构,会有许许多许多、形形色色的widget,每个都是一个窗口。对象与窗口之间的映射可能就是个不 小的问题,像MFC那样搞?太落伍了吧!用thunk就要简单的多。WTL用了thunk,但是不够彻底。
废话少说,先贴出thunk核心代码。

Read more »

最近在玩boost,用vc++ 2008 express编译最新版本1.39时遇到一点小问题,记录于此。
分别下载了zlib,bzip2和icu,python暂时不玩,没接触过。我喜欢静态链接程序,根据官方文档的提示,在console输入如下指令,为了输入方便,最好写个bat脚本:

bootstrap
bjam -sBZIP2_SOURCE=D:/libs/bzip2-1.0.5 -sZLIB_SOURCE=D:/libs/zlib-1.2.3 -sHAVE_ICU=1 -sICU_PATH=D:/libs/icu link=static runtime-link=static threading=multi –without-python

console窗口一阵晃动后吐出了这么三行error:

error: link=shared together with runtime-link=static is not allowed
error: such property combination is either impossible
error: or too dangerious to be of any use

百思不得其解,明明我的link选项只有static,哪来的shared啊,郁闷啊郁闷,反复折腾后,发现,如果没有ICU选项,则不会出现此错误提示。

用vim打开boost_1_39_0\libs\regex\build\jamfile.v2,搜索一下/\<shared\>,果然在文件底部,218,223和229行链接选项被写死为shared。那就去掉这该死的shared,重新来过,bjam终于开始正常工作了。

编译带ICU选项的regex还会遇到一点儿小问题。boost.regex期望的icui18n.lib和icudata.lib与编译后的ICU库的名字并不相同,简单修改一下就可以了,如下:
libs\icu\lib\icuin.lib -> icui18n.lib
libs\icu\lib\icudt.lib -> icudata.lib

测试了boost 1.39官方文档的regex测试程序,静态链接,一切OK。

新版本bash(可能从3.0以后)内置了运算符 =~ 来支持正则表达式匹配。请注意此运算符只能用在[[…]]表达式中,而不能用在[…] 中。bash内置支持的好处在于使用方便和效率提升,不需要fork一个process即可以进行正则表达式匹配。但是似乎bash对正则表达式的支持不很完善,比如用 转义符\d无法匹配单个数字,必须用 [0-9]来匹配才行,比较罗嗦。

Read more »

当我们说到sticky位(t)时,一般都是在说“在设置了sticky位(t)的目录下,用户只能删除属于自己的文件”,其实这样说并不确切。在网上找了几篇文章后 还是没有找到比较权威的解释,man一下chmod可以发现一段对该位的详细解释,说的很明白。翻译如下以备忘。原文见man chmod(1)。

“限制删除标志和粘滞位共用一个位,系统依赖于文件类型来解释此位。对于目录,该位阻止非授权用户删除或重命名本目录下的文件除非该用户是文件或目录的属 主,这就是所谓的目录的限制删除标志,通常在所有人都可写的目录/tmp上可以发现该标志。在一些老旧系统的普通程序文件上,该位使系统在交换设备上保存程序的映像从而使程序可以更快的再次运行,这就是所谓的粘滞位。”

所以当该位用于目录权限设置时,叫做“限制删除标志位”更合适。

PS:此文最早发表于cppblog.

===
[erq]

前几天刚安装了ubuntu 9.04,在分区的时候,先从磁盘的最后面划出大约2G的空间做了swap,然后再分的/,/var,/tmp,/home。安装好了才发现,虽然swap在磁盘的最后面,其设备号却为/dev/sda6,排在其他分区的前面,sda1和sda5为XP使用的分区。虽然看着有些不爽,但是不影响使用,也就没管它。

今天用sudo fdisk -l查看分区表的时,在打印的分区列表最后面有一句话:Partition table entries are not in disk order,又勾起了我的洁癖,决定把分区表顺序调整过来。

sudo fdisk /dev/sda进入fdisk的shell,然后输入f回车就可以把分区顺序调整过来了,然后输入w保存退出。因为root分区的设备号从(hd0,6)变成了(hd0,5),所以grub就会无法找到root分区,从而无法进行引导。

用ubuntu 9.04的livecd引导进入系统,进入grub,然后root (hd0,5),setup (hd0) 就可以了。
ubuntu9.04是用uuid来标示分区的,所以/etc/fstab和/boot/grub/menu.lst不用更改就可以顺利的启动系统了。

utf8是我很喜欢的的字符集,在我的Debian lenny上安装mysql后,默认的字符集是latin1,现在就让我们把mysql相关的所有默认字符集都更改为utf8。

在/etc/mysql/conf.d目录下面新建一个文件charset.cnf,增加如下内容:
[client]
default-character-set = utf8
[mysql]
default-character-set = utf8
[mysqld]
default-character-set =utf8

然后执行命令sudo /etc/init.d/mysql reload,现在连上你的数据库看看吧,默认的字符集和校对集全部变成了utf8。

在自己的主目录下面建了一个bin子目录,把自己撰写的一些简单的脚本放在这里执行,因为debian lenny用户主目录下的.profile文件默认把$HOME/bin路径放入了环境变量$PATH中,因此自撰的脚本就可以像系统提供的应用程序一样来运行了。

但是今天写了一个脚本需要root权限来运行,sudo一下居然提示”sudo:  xxx.sh:  command not found”。很明显这是$PATH的问题,切换到root,设置好$PATH,运行这个脚本是没问题的。看来是sudo的问题了,浏览了sudo的man page,然后google了一下后发现了问题所在。

原来Debian在编译sudo包的时候默认开启了- -with-secure-path选项,在我机器上这个完整的选项是: - -with-secure-path=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin”。当sudo时$PATH变量就会被secure-path所代替,所以即便你更改/etc/environment中的PATH也没有用。此问题由来已久,没想到在lenny中仍然存在。

后来有一个sudo options SECURE_PATH可以override此内置设置,在/etc/sudoers文件内增加这么一行:

Defaults secure_path=”/bin:/usr/bin:/usr/local/bin:…”
但是这样很不方便。

其他的workround我知道有这么几个:
1、使用脚本的完全路径,不是办法的办法。
2、使用sudo的env选项,像这样sudo env PATH=$PATH xxx.sh
3、把脚本拷贝或链接到系统$PATH中

这些方法都很别扭,所以最终的解决方案就是:
重新编译sudo,千万别再带- -with-secure-path选项了。