SWT: 深入内幕之消息机制探秘

CSDN Blog似乎不允许上传除图片以外的其他文件。然而,这篇文章我不得不用PDF来做——或许因为格式比较复杂,代码很多,在使用另外一个blog系统的HTML编辑器时频频出现脚本错误。最终我不得不放弃,转而在自己的机器上完成文章编辑。因此,最后的结果是一个PDF。CSDN的编辑器是否会出现同样的问题我不得而知,不过我已经不希望再重新编辑一遍了。


如果看过下面的文章序言以后,你对它感兴趣的话,那么请到这个地方下载PDF:
http://www.yousendit.com/transfer.php?action=download&ufid=19BF243E3E7F9D9C


如果你不了解SWT,或者虽然了解、但是只想使用它而不关心其内幕,那么这篇文章不适合你。


前言

作为一个专注于C/S方面开发的程序员,我一直对“面向对象的编程框架如何与Windows操作系统
的消息机制打交道”这个问题有着相当大的兴趣。读者想必知道,象MFC、VCL和SWT这样的类
库在实现界面处理的时候,有几个主要问题是不得不考虑的。首先是如何为窗口和控件这样的界面
组件以面向对象方式进行包装。这一方面可以说没多少技术上的难题;从一般意义上讲,不过是把
HWND 作为第一个参数的函数分类整理一下而已。当然,具体作起来还是有不少东西需要认真考虑,
只是这些问题多半是在设计的层面,考虑包装是否完善、维护和扩展起来是否方便等等;实现上基
本上就没多少需要克服的技术障碍了。而另一方面——即如何处理系统消息机制,则是一个颇费脑
筋的问题了。其中最大的难点之一,就是Windows的消息系统依赖于窗口过程(术语叫做Window
Procedure),而这个窗口过程却是一个非面向对象的、普通的全局函数,它完全不理解对象是什么;
可是而为了让整个程序OO 起来,你还非得让它去操纵对象不可。因此,如何将窗口过程用面向对
象的方法完美的封装起来,就成为各种类库面临的最大挑战之一。当然,这也理所当然的成为各个
开发小组展示自身功力的绝好舞台。

据我所知,在此一问题上,不同的类库使用了不同的解决方案。较早的MFC 使用了窗口查找表的
技术,即为每个窗口和对应的窗口过程建立一个映射;需要处理消息的时候,则是映射表中找到窗
口所对应的过程,并调用之。这样会带来几个问题。首先是每次进行查表势必浪费时间,为此MFC
不惜在关键处使用Cache映射和内联汇编的方法以提高效率。第二个问题:映射表是和线程相关联
的,如果你将窗口传递给另外一个线程,MFC无法在该线程中找到窗口的映射项,也就不知该如何
是好,于是只好出错。我已经在很多地方看到有人问跨线程传递窗口指针的疑问,多半都是因为不
理解MFC的消息处理机制。正因为如此,MFC的使用者必须强制遵守一些调用方面的约定,否则
会出现很多莫名其妙的错误,这无疑是框架不够友好的表现。而稍晚出现的VCL 和ATL 则使用了
一种比较巧妙的Thunk技术,利用函数调用过程中使用堆栈的原理,巧妙的将对象指针“暗度陈仓”
地偷偷传递进去,并通过一些内存中的“小动作”越过了通常的处理机制。这样做的好处是节省了
额外维护映射表的开销,速度相当快,同时也不存在线程传递的问题。当然,这个过程因为大量使
用汇编,而且需要对函数调用的底层机制有深刻的理解,所以很难为一般程序员所理解和运用。(相
应的维护起来也难度也比较高——还记得Anders离开Borland以后相当长时间没有人敢改动Delphi
底层代码的往事吗?)

在众多框架中,SWT 算是比较年轻的一个,也是颇为独特的一个。之所以说它特殊,因为它是用
Java 编写的。我们知道,和Windows 平台上的本地开发工具不同,Java 程序是生活在自己的虚拟机
中的,除非通过JNI 这个后门,否则它对底下的操作系统基本上一无所知。这显然为设计者提出了
更高的挑战。那么,SWT又是如何实现这一点的呢?非常幸运,SWT是完全开放源代码的(当然,
MFC 和VCL 也是开放的,不过这种开放就稍显小家子气——许多时候你必须购买昂贵的企业版才
能看到这些宝贵的源码,D版且不论)。开放源代码为我们研究其实现扫清了障碍。

由于使用SWT 的过程中遇到一些障碍,我开始考虑有没有突破其限制的办法,也以此为契机阅读
了SWT 的部分源代码,了解到其中一些底层的东西。本文可以说是这次研究的副产品。我把自己
的一些心得整理出来,希望有类似爱好的朋友能从中发现一些有趣的东西。当然,更希望对SWT
有丰富经验的读者来批评指正。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值